@shd101wyy/yo 0.0.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 (339) hide show
  1. package/LICENSE.md +17 -0
  2. package/README.md +80 -0
  3. package/out/cjs/index.cjs +51 -0
  4. package/out/cjs/yo-cli.cjs +2158 -0
  5. package/out/esm/index.mjs +51 -0
  6. package/out/types/src/codegen/async/runtime.d.ts +2 -0
  7. package/out/types/src/codegen/async/state-code-gen.d.ts +10 -0
  8. package/out/types/src/codegen/async/state-machine.d.ts +13 -0
  9. package/out/types/src/codegen/c/collection.d.ts +3 -0
  10. package/out/types/src/codegen/codegen-c.d.ts +12 -0
  11. package/out/types/src/codegen/constants.d.ts +3 -0
  12. package/out/types/src/codegen/expressions/array.d.ts +4 -0
  13. package/out/types/src/codegen/expressions/generation.d.ts +11 -0
  14. package/out/types/src/codegen/expressions/index.d.ts +2 -0
  15. package/out/types/src/codegen/functions/collection.d.ts +5 -0
  16. package/out/types/src/codegen/functions/context.d.ts +57 -0
  17. package/out/types/src/codegen/functions/generation.d.ts +25 -0
  18. package/out/types/src/codegen/functions/index.d.ts +2 -0
  19. package/out/types/src/codegen/index.d.ts +20 -0
  20. package/out/types/src/codegen/parallelism/runtime.d.ts +2 -0
  21. package/out/types/src/codegen/types/collection.d.ts +8 -0
  22. package/out/types/src/codegen/types/generation.d.ts +13 -0
  23. package/out/types/src/codegen/types/index.d.ts +2 -0
  24. package/out/types/src/codegen/utils/fixup.d.ts +2 -0
  25. package/out/types/src/codegen/utils/index.d.ts +77 -0
  26. package/out/types/src/codegen/values/index.d.ts +1 -0
  27. package/out/types/src/emitter.d.ts +11 -0
  28. package/out/types/src/env.d.ts +85 -0
  29. package/out/types/src/error.d.ts +45 -0
  30. package/out/types/src/evaluator/async/await-analysis-types.d.ts +23 -0
  31. package/out/types/src/evaluator/async/await-analysis.d.ts +5 -0
  32. package/out/types/src/evaluator/builtins/alignof.d.ts +8 -0
  33. package/out/types/src/evaluator/builtins/and_or.d.ts +8 -0
  34. package/out/types/src/evaluator/builtins/arc_fns.d.ts +58 -0
  35. package/out/types/src/evaluator/builtins/array_fns.d.ts +0 -0
  36. package/out/types/src/evaluator/builtins/as.d.ts +8 -0
  37. package/out/types/src/evaluator/builtins/async_fns.d.ts +8 -0
  38. package/out/types/src/evaluator/builtins/compt_assert.d.ts +8 -0
  39. package/out/types/src/evaluator/builtins/compt_boolean_fns.d.ts +8 -0
  40. package/out/types/src/evaluator/builtins/compt_expect_error.d.ts +8 -0
  41. package/out/types/src/evaluator/builtins/compt_list_fns.d.ts +33 -0
  42. package/out/types/src/evaluator/builtins/compt_print.d.ts +8 -0
  43. package/out/types/src/evaluator/builtins/compt_string_fns.d.ts +8 -0
  44. package/out/types/src/evaluator/builtins/consume.d.ts +8 -0
  45. package/out/types/src/evaluator/builtins/drop.d.ts +8 -0
  46. package/out/types/src/evaluator/builtins/dup.d.ts +8 -0
  47. package/out/types/src/evaluator/builtins/expr_fns.d.ts +33 -0
  48. package/out/types/src/evaluator/builtins/future_fns.d.ts +8 -0
  49. package/out/types/src/evaluator/builtins/gc.d.ts +8 -0
  50. package/out/types/src/evaluator/builtins/gensym.d.ts +8 -0
  51. package/out/types/src/evaluator/builtins/impl_constraint.d.ts +8 -0
  52. package/out/types/src/evaluator/builtins/macro_expand.d.ts +8 -0
  53. package/out/types/src/evaluator/builtins/numeric_fns.d.ts +8 -0
  54. package/out/types/src/evaluator/builtins/panic.d.ts +8 -0
  55. package/out/types/src/evaluator/builtins/ptr_fns.d.ts +8 -0
  56. package/out/types/src/evaluator/builtins/quote.d.ts +13 -0
  57. package/out/types/src/evaluator/builtins/rc.d.ts +8 -0
  58. package/out/types/src/evaluator/builtins/sizeof.d.ts +8 -0
  59. package/out/types/src/evaluator/builtins/the.d.ts +8 -0
  60. package/out/types/src/evaluator/builtins/type_fns.d.ts +28 -0
  61. package/out/types/src/evaluator/builtins/va_start.d.ts +8 -0
  62. package/out/types/src/evaluator/builtins/var_fns.d.ts +18 -0
  63. package/out/types/src/evaluator/calls/array.d.ts +13 -0
  64. package/out/types/src/evaluator/calls/array_type.d.ts +11 -0
  65. package/out/types/src/evaluator/calls/closure_type.d.ts +11 -0
  66. package/out/types/src/evaluator/calls/compt_function.d.ts +19 -0
  67. package/out/types/src/evaluator/calls/compt_list_type.d.ts +11 -0
  68. package/out/types/src/evaluator/calls/function.d.ts +16 -0
  69. package/out/types/src/evaluator/calls/function_type.d.ts +15 -0
  70. package/out/types/src/evaluator/calls/helper.d.ts +42 -0
  71. package/out/types/src/evaluator/calls/iso.d.ts +15 -0
  72. package/out/types/src/evaluator/calls/module_type.d.ts +11 -0
  73. package/out/types/src/evaluator/calls/numeric_type.d.ts +15 -0
  74. package/out/types/src/evaluator/calls/pointer.d.ts +8 -0
  75. package/out/types/src/evaluator/calls/pointer_type.d.ts +14 -0
  76. package/out/types/src/evaluator/calls/type.d.ts +12 -0
  77. package/out/types/src/evaluator/context.d.ts +169 -0
  78. package/out/types/src/evaluator/exprs/_expr.d.ts +8 -0
  79. package/out/types/src/evaluator/exprs/assignment.d.ts +9 -0
  80. package/out/types/src/evaluator/exprs/begin.d.ts +10 -0
  81. package/out/types/src/evaluator/exprs/binding.d.ts +12 -0
  82. package/out/types/src/evaluator/exprs/c_include.d.ts +8 -0
  83. package/out/types/src/evaluator/exprs/cond.d.ts +8 -0
  84. package/out/types/src/evaluator/exprs/destructuring_assignment.d.ts +33 -0
  85. package/out/types/src/evaluator/exprs/exists.d.ts +0 -0
  86. package/out/types/src/evaluator/exprs/expr.d.ts +9 -0
  87. package/out/types/src/evaluator/exprs/extern.d.ts +8 -0
  88. package/out/types/src/evaluator/exprs/identifer_and_operator.d.ts +9 -0
  89. package/out/types/src/evaluator/exprs/import.d.ts +9 -0
  90. package/out/types/src/evaluator/exprs/initialization_assignment.d.ts +8 -0
  91. package/out/types/src/evaluator/exprs/match.d.ts +8 -0
  92. package/out/types/src/evaluator/exprs/open.d.ts +8 -0
  93. package/out/types/src/evaluator/exprs/property_access.d.ts +8 -0
  94. package/out/types/src/evaluator/exprs/recur.d.ts +8 -0
  95. package/out/types/src/evaluator/exprs/subtype_of.d.ts +21 -0
  96. package/out/types/src/evaluator/exprs/test.d.ts +8 -0
  97. package/out/types/src/evaluator/exprs/typeof.d.ts +8 -0
  98. package/out/types/src/evaluator/exprs/while.d.ts +8 -0
  99. package/out/types/src/evaluator/index.d.ts +26 -0
  100. package/out/types/src/evaluator/types/array.d.ts +8 -0
  101. package/out/types/src/evaluator/types/closure.d.ts +8 -0
  102. package/out/types/src/evaluator/types/compt_list.d.ts +8 -0
  103. package/out/types/src/evaluator/types/concrete_module.d.ts +8 -0
  104. package/out/types/src/evaluator/types/dyn.d.ts +8 -0
  105. package/out/types/src/evaluator/types/enum.d.ts +8 -0
  106. package/out/types/src/evaluator/types/expr_synthesizer.d.ts +14 -0
  107. package/out/types/src/evaluator/types/field.d.ts +14 -0
  108. package/out/types/src/evaluator/types/fn_module.d.ts +8 -0
  109. package/out/types/src/evaluator/types/function.d.ts +58 -0
  110. package/out/types/src/evaluator/types/future_module.d.ts +8 -0
  111. package/out/types/src/evaluator/types/module.d.ts +19 -0
  112. package/out/types/src/evaluator/types/newtype.d.ts +8 -0
  113. package/out/types/src/evaluator/types/object.d.ts +8 -0
  114. package/out/types/src/evaluator/types/proofs.d.ts +0 -0
  115. package/out/types/src/evaluator/types/slice.d.ts +8 -0
  116. package/out/types/src/evaluator/types/struct.d.ts +8 -0
  117. package/out/types/src/evaluator/types/synthesizer.d.ts +16 -0
  118. package/out/types/src/evaluator/types/tuple.d.ts +18 -0
  119. package/out/types/src/evaluator/types/union.d.ts +8 -0
  120. package/out/types/src/evaluator/types/utils.d.ts +71 -0
  121. package/out/types/src/evaluator/types/validation.d.ts +3 -0
  122. package/out/types/src/evaluator/utils/array-utils.d.ts +15 -0
  123. package/out/types/src/evaluator/utils/closure.d.ts +35 -0
  124. package/out/types/src/evaluator/utils.d.ts +4 -0
  125. package/out/types/src/evaluator/values/anonymous_function.d.ts +8 -0
  126. package/out/types/src/evaluator/values/anonymous_module.d.ts +17 -0
  127. package/out/types/src/evaluator/values/anonymous_struct.d.ts +8 -0
  128. package/out/types/src/evaluator/values/array.d.ts +8 -0
  129. package/out/types/src/evaluator/values/boolean.d.ts +3 -0
  130. package/out/types/src/evaluator/values/char.d.ts +3 -0
  131. package/out/types/src/evaluator/values/compt_list.d.ts +8 -0
  132. package/out/types/src/evaluator/values/dyn.d.ts +8 -0
  133. package/out/types/src/evaluator/values/float.d.ts +4 -0
  134. package/out/types/src/evaluator/values/integer.d.ts +4 -0
  135. package/out/types/src/evaluator/values/module.d.ts +58 -0
  136. package/out/types/src/evaluator/values/string.d.ts +3 -0
  137. package/out/types/src/evaluator/values/tuple.d.ts +32 -0
  138. package/out/types/src/expr.d.ts +456 -0
  139. package/out/types/src/function-value.d.ts +42 -0
  140. package/out/types/src/index.d.ts +4 -0
  141. package/out/types/src/lexer.d.ts +2 -0
  142. package/out/types/src/logger.d.ts +1 -0
  143. package/out/types/src/module-manager.d.ts +30 -0
  144. package/out/types/src/naming-checker.d.ts +4 -0
  145. package/out/types/src/parser.d.ts +33 -0
  146. package/out/types/src/test-runner.d.ts +30 -0
  147. package/out/types/src/tests/codegen.test.d.ts +1 -0
  148. package/out/types/src/tests/fixme.test.d.ts +1 -0
  149. package/out/types/src/tests/module-manager.test.d.ts +1 -0
  150. package/out/types/src/tests/parser.test.d.ts +1 -0
  151. package/out/types/src/tests/sample.test.d.ts +0 -0
  152. package/out/types/src/tests/std.test.d.ts +1 -0
  153. package/out/types/src/token.d.ts +40 -0
  154. package/out/types/src/type-value.d.ts +7 -0
  155. package/out/types/src/types/compatibility.d.ts +16 -0
  156. package/out/types/src/types/creators.d.ts +73 -0
  157. package/out/types/src/types/definitions.d.ts +218 -0
  158. package/out/types/src/types/guards.d.ts +70 -0
  159. package/out/types/src/types/hierarchy.d.ts +4 -0
  160. package/out/types/src/types/index.d.ts +7 -0
  161. package/out/types/src/types/module_field.d.ts +2 -0
  162. package/out/types/src/types/tags.d.ts +45 -0
  163. package/out/types/src/types/utils.d.ts +50 -0
  164. package/out/types/src/unit-value.d.ts +7 -0
  165. package/out/types/src/utils.d.ts +6 -0
  166. package/out/types/src/value-tag.d.ts +29 -0
  167. package/out/types/src/value.d.ts +110 -0
  168. package/out/types/src/yo-cli.d.ts +1 -0
  169. package/out/types/tsconfig.tsbuildinfo +1 -0
  170. package/package.json +57 -0
  171. package/scripts/check-liburing.js +76 -0
  172. package/std/alg/hash.yo +50 -0
  173. package/std/allocator.yo +113 -0
  174. package/std/allocators/c_allocator.yo +118 -0
  175. package/std/async.yo +13 -0
  176. package/std/collections/array_list.yo +415 -0
  177. package/std/collections/hash_map.yo +482 -0
  178. package/std/collections/hash_set.yo +706 -0
  179. package/std/collections/index.yo +11 -0
  180. package/std/collections/linked_list.yo +439 -0
  181. package/std/error.yo +0 -0
  182. package/std/gc.yo +10 -0
  183. package/std/index.yo +12 -0
  184. package/std/io/file.yo +191 -0
  185. package/std/io/index.yo +5 -0
  186. package/std/libc/assert.yo +39 -0
  187. package/std/libc/ctype.yo +57 -0
  188. package/std/libc/errno.yo +182 -0
  189. package/std/libc/float.yo +87 -0
  190. package/std/libc/index.yo +29 -0
  191. package/std/libc/limits.yo +65 -0
  192. package/std/libc/math.yo +679 -0
  193. package/std/libc/signal.yo +101 -0
  194. package/std/libc/stdatomic.yo +213 -0
  195. package/std/libc/stdint.yo +214 -0
  196. package/std/libc/stdio.yo +225 -0
  197. package/std/libc/stdlib.yo +204 -0
  198. package/std/libc/string.yo +151 -0
  199. package/std/libc/time.yo +92 -0
  200. package/std/libc/unistd.yo +130 -0
  201. package/std/monad.yo +152 -0
  202. package/std/prelude.yo +3094 -0
  203. package/std/string/index.yo +8 -0
  204. package/std/string/rune.yo +82 -0
  205. package/std/string/string.yo +288 -0
  206. package/std/sync.yo +95 -0
  207. package/std/thread.yo +36 -0
  208. package/std/time.yo +13 -0
  209. package/std/worker.yo +36 -0
  210. package/vendor/mimalloc/.gitattributes +12 -0
  211. package/vendor/mimalloc/CMakeLists.txt +763 -0
  212. package/vendor/mimalloc/LICENSE +21 -0
  213. package/vendor/mimalloc/SECURITY.md +41 -0
  214. package/vendor/mimalloc/azure-pipelines.yml +251 -0
  215. package/vendor/mimalloc/bin/mimalloc-redirect-arm64.dll +0 -0
  216. package/vendor/mimalloc/bin/mimalloc-redirect-arm64.lib +0 -0
  217. package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.dll +0 -0
  218. package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.lib +0 -0
  219. package/vendor/mimalloc/bin/mimalloc-redirect.dll +0 -0
  220. package/vendor/mimalloc/bin/mimalloc-redirect.lib +0 -0
  221. package/vendor/mimalloc/bin/mimalloc-redirect32.dll +0 -0
  222. package/vendor/mimalloc/bin/mimalloc-redirect32.lib +0 -0
  223. package/vendor/mimalloc/bin/minject-arm64.exe +0 -0
  224. package/vendor/mimalloc/bin/minject.exe +0 -0
  225. package/vendor/mimalloc/bin/minject32.exe +0 -0
  226. package/vendor/mimalloc/bin/readme.md +118 -0
  227. package/vendor/mimalloc/cmake/JoinPaths.cmake +23 -0
  228. package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +19 -0
  229. package/vendor/mimalloc/cmake/mimalloc-config.cmake +14 -0
  230. package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +23 -0
  231. package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +28 -0
  232. package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +28 -0
  233. package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +23 -0
  234. package/vendor/mimalloc/contrib/docker/readme.md +10 -0
  235. package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +64 -0
  236. package/vendor/mimalloc/contrib/vcpkg/readme.md +40 -0
  237. package/vendor/mimalloc/contrib/vcpkg/usage +20 -0
  238. package/vendor/mimalloc/contrib/vcpkg/vcpkg-cmake-wrapper.cmake +20 -0
  239. package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +48 -0
  240. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg +887 -0
  241. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg +1185 -0
  242. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg +757 -0
  243. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg +1028 -0
  244. package/vendor/mimalloc/doc/bench-2020/bench-r5a-1.svg +769 -0
  245. package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg +868 -0
  246. package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg +1157 -0
  247. package/vendor/mimalloc/doc/bench-2020/bench-r5a-2.svg +983 -0
  248. package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg +683 -0
  249. package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg +854 -0
  250. package/vendor/mimalloc/doc/bench-2020/bench-spec-rss.svg +713 -0
  251. package/vendor/mimalloc/doc/bench-2020/bench-spec.svg +713 -0
  252. package/vendor/mimalloc/doc/bench-2020/bench-z4-1.svg +890 -0
  253. package/vendor/mimalloc/doc/bench-2020/bench-z4-2.svg +1146 -0
  254. package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-1.svg +796 -0
  255. package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-2.svg +974 -0
  256. package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg +952 -0
  257. package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg +1255 -0
  258. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg +955 -0
  259. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg +1269 -0
  260. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg +836 -0
  261. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg +1131 -0
  262. package/vendor/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg +766 -0
  263. package/vendor/mimalloc/doc/doxyfile +2895 -0
  264. package/vendor/mimalloc/doc/ds-logo.jpg +0 -0
  265. package/vendor/mimalloc/doc/ds-logo.png +0 -0
  266. package/vendor/mimalloc/doc/mimalloc-doc.h +1452 -0
  267. package/vendor/mimalloc/doc/mimalloc-doxygen.css +60 -0
  268. package/vendor/mimalloc/doc/mimalloc-logo-100.png +0 -0
  269. package/vendor/mimalloc/doc/mimalloc-logo.png +0 -0
  270. package/vendor/mimalloc/doc/mimalloc-logo.svg +161 -0
  271. package/vendor/mimalloc/doc/spades-logo.png +0 -0
  272. package/vendor/mimalloc/doc/unreal-logo.svg +43 -0
  273. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +500 -0
  274. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj.filters +108 -0
  275. package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj +508 -0
  276. package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj.filters +111 -0
  277. package/vendor/mimalloc/ide/vs2022/mimalloc-override-test-dep.vcxproj +355 -0
  278. package/vendor/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj +360 -0
  279. package/vendor/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj +295 -0
  280. package/vendor/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj +292 -0
  281. package/vendor/mimalloc/ide/vs2022/mimalloc-test.vcxproj +289 -0
  282. package/vendor/mimalloc/ide/vs2022/mimalloc.sln +151 -0
  283. package/vendor/mimalloc/include/mimalloc/atomic.h +557 -0
  284. package/vendor/mimalloc/include/mimalloc/internal.h +1153 -0
  285. package/vendor/mimalloc/include/mimalloc/prim.h +421 -0
  286. package/vendor/mimalloc/include/mimalloc/track.h +145 -0
  287. package/vendor/mimalloc/include/mimalloc/types.h +685 -0
  288. package/vendor/mimalloc/include/mimalloc-new-delete.h +66 -0
  289. package/vendor/mimalloc/include/mimalloc-override.h +68 -0
  290. package/vendor/mimalloc/include/mimalloc-stats.h +103 -0
  291. package/vendor/mimalloc/include/mimalloc.h +612 -0
  292. package/vendor/mimalloc/mimalloc.pc.in +11 -0
  293. package/vendor/mimalloc/readme.md +946 -0
  294. package/vendor/mimalloc/src/alloc-aligned.c +360 -0
  295. package/vendor/mimalloc/src/alloc-override.c +316 -0
  296. package/vendor/mimalloc/src/alloc-posix.c +185 -0
  297. package/vendor/mimalloc/src/alloc.c +692 -0
  298. package/vendor/mimalloc/src/arena-abandon.c +346 -0
  299. package/vendor/mimalloc/src/arena.c +1043 -0
  300. package/vendor/mimalloc/src/bitmap.c +441 -0
  301. package/vendor/mimalloc/src/bitmap.h +119 -0
  302. package/vendor/mimalloc/src/free.c +572 -0
  303. package/vendor/mimalloc/src/heap.c +733 -0
  304. package/vendor/mimalloc/src/init.c +714 -0
  305. package/vendor/mimalloc/src/libc.c +334 -0
  306. package/vendor/mimalloc/src/options.c +663 -0
  307. package/vendor/mimalloc/src/os.c +770 -0
  308. package/vendor/mimalloc/src/page-queue.c +390 -0
  309. package/vendor/mimalloc/src/page.c +1049 -0
  310. package/vendor/mimalloc/src/prim/emscripten/prim.c +249 -0
  311. package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +461 -0
  312. package/vendor/mimalloc/src/prim/osx/prim.c +9 -0
  313. package/vendor/mimalloc/src/prim/prim.c +76 -0
  314. package/vendor/mimalloc/src/prim/readme.md +9 -0
  315. package/vendor/mimalloc/src/prim/unix/prim.c +934 -0
  316. package/vendor/mimalloc/src/prim/wasi/prim.c +284 -0
  317. package/vendor/mimalloc/src/prim/windows/etw-mimalloc.wprp +61 -0
  318. package/vendor/mimalloc/src/prim/windows/etw.h +905 -0
  319. package/vendor/mimalloc/src/prim/windows/etw.man +0 -0
  320. package/vendor/mimalloc/src/prim/windows/prim.c +878 -0
  321. package/vendor/mimalloc/src/prim/windows/readme.md +17 -0
  322. package/vendor/mimalloc/src/random.c +258 -0
  323. package/vendor/mimalloc/src/segment-map.c +142 -0
  324. package/vendor/mimalloc/src/segment.c +1702 -0
  325. package/vendor/mimalloc/src/static.c +41 -0
  326. package/vendor/mimalloc/src/stats.c +635 -0
  327. package/vendor/mimalloc/test/CMakeLists.txt +56 -0
  328. package/vendor/mimalloc/test/main-override-dep.cpp +51 -0
  329. package/vendor/mimalloc/test/main-override-dep.h +11 -0
  330. package/vendor/mimalloc/test/main-override-static.c +539 -0
  331. package/vendor/mimalloc/test/main-override.c +36 -0
  332. package/vendor/mimalloc/test/main-override.cpp +497 -0
  333. package/vendor/mimalloc/test/main.c +46 -0
  334. package/vendor/mimalloc/test/readme.md +16 -0
  335. package/vendor/mimalloc/test/test-api-fill.c +343 -0
  336. package/vendor/mimalloc/test/test-api.c +466 -0
  337. package/vendor/mimalloc/test/test-stress.c +428 -0
  338. package/vendor/mimalloc/test/test-wrong.c +92 -0
  339. package/vendor/mimalloc/test/testhelper.h +49 -0
@@ -0,0 +1,692 @@
1
+ /* ----------------------------------------------------------------------------
2
+ Copyright (c) 2018-2024, Microsoft Research, Daan Leijen
3
+ This is free software; you can redistribute it and/or modify it under the
4
+ terms of the MIT license. A copy of the license can be found in the file
5
+ "LICENSE" at the root of this distribution.
6
+ -----------------------------------------------------------------------------*/
7
+ #ifndef _DEFAULT_SOURCE
8
+ #define _DEFAULT_SOURCE // for realpath() on Linux
9
+ #endif
10
+
11
+ #include "mimalloc.h"
12
+ #include "mimalloc/internal.h"
13
+ #include "mimalloc/atomic.h"
14
+ #include "mimalloc/prim.h" // _mi_prim_thread_id()
15
+
16
+ #include <string.h> // memset, strlen (for mi_strdup)
17
+ #include <stdlib.h> // malloc, abort
18
+
19
+ #define MI_IN_ALLOC_C
20
+ #include "alloc-override.c"
21
+ #include "free.c"
22
+ #undef MI_IN_ALLOC_C
23
+
24
+ // ------------------------------------------------------
25
+ // Allocation
26
+ // ------------------------------------------------------
27
+
28
+ // Fast allocation in a page: just pop from the free list.
29
+ // Fall back to generic allocation only if the list is empty.
30
+ // Note: in release mode the (inlined) routine is about 7 instructions with a single test.
31
+ extern inline void* _mi_page_malloc_zero(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept
32
+ {
33
+ mi_assert_internal(size >= MI_PADDING_SIZE);
34
+ mi_assert_internal(page->block_size == 0 /* empty heap */ || mi_page_block_size(page) >= size);
35
+
36
+ // check the free list
37
+ mi_block_t* const block = page->free;
38
+ if mi_unlikely(block == NULL) {
39
+ return _mi_malloc_generic(heap, size, zero, 0);
40
+ }
41
+ mi_assert_internal(block != NULL && _mi_ptr_page(block) == page);
42
+
43
+ // pop from the free list
44
+ page->free = mi_block_next(page, block);
45
+ page->used++;
46
+ mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page);
47
+ mi_assert_internal(page->block_size < MI_MAX_ALIGN_SIZE || _mi_is_aligned(block, MI_MAX_ALIGN_SIZE));
48
+
49
+ #if MI_DEBUG>3
50
+ if (page->free_is_zero && size > sizeof(*block)) {
51
+ mi_assert_expensive(mi_mem_is_zero(block+1,size - sizeof(*block)));
52
+ }
53
+ #endif
54
+
55
+ // allow use of the block internally
56
+ // note: when tracking we need to avoid ever touching the MI_PADDING since
57
+ // that is tracked by valgrind etc. as non-accessible (through the red-zone, see `mimalloc/track.h`)
58
+ mi_track_mem_undefined(block, mi_page_usable_block_size(page));
59
+
60
+ // zero the block? note: we need to zero the full block size (issue #63)
61
+ if mi_unlikely(zero) {
62
+ mi_assert_internal(page->block_size != 0); // do not call with zero'ing for huge blocks (see _mi_malloc_generic)
63
+ mi_assert_internal(!mi_page_is_huge(page));
64
+ #if MI_PADDING
65
+ mi_assert_internal(page->block_size >= MI_PADDING_SIZE);
66
+ #endif
67
+ if (page->free_is_zero) {
68
+ block->next = 0;
69
+ mi_track_mem_defined(block, page->block_size - MI_PADDING_SIZE);
70
+ }
71
+ else {
72
+ _mi_memzero_aligned(block, page->block_size - MI_PADDING_SIZE);
73
+ }
74
+ }
75
+
76
+ #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN
77
+ if (!zero && !mi_page_is_huge(page)) {
78
+ memset(block, MI_DEBUG_UNINIT, mi_page_usable_block_size(page));
79
+ }
80
+ #elif (MI_SECURE!=0)
81
+ if (!zero) { block->next = 0; } // don't leak internal data
82
+ #endif
83
+
84
+ #if (MI_STAT>0)
85
+ const size_t bsize = mi_page_usable_block_size(page);
86
+ if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) {
87
+ mi_heap_stat_increase(heap, malloc_normal, bsize);
88
+ mi_heap_stat_counter_increase(heap, malloc_normal_count, 1);
89
+ #if (MI_STAT>1)
90
+ const size_t bin = _mi_bin(bsize);
91
+ mi_heap_stat_increase(heap, malloc_bins[bin], 1);
92
+ mi_heap_stat_increase(heap, malloc_requested, size - MI_PADDING_SIZE);
93
+ #endif
94
+ }
95
+ #endif
96
+
97
+ #if MI_PADDING // && !MI_TRACK_ENABLED
98
+ mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + mi_page_usable_block_size(page));
99
+ ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE));
100
+ #if (MI_DEBUG>=2)
101
+ mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta));
102
+ #endif
103
+ mi_track_mem_defined(padding,sizeof(mi_padding_t)); // note: re-enable since mi_page_usable_block_size may set noaccess
104
+ padding->canary = mi_ptr_encode_canary(page,block,page->keys);
105
+ padding->delta = (uint32_t)(delta);
106
+ #if MI_PADDING_CHECK
107
+ if (!mi_page_is_huge(page)) {
108
+ uint8_t* fill = (uint8_t*)padding - delta;
109
+ const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes
110
+ for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; }
111
+ }
112
+ #endif
113
+ #endif
114
+
115
+ return block;
116
+ }
117
+
118
+ // extra entries for improved efficiency in `alloc-aligned.c`.
119
+ extern void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept {
120
+ return _mi_page_malloc_zero(heap,page,size,false);
121
+ }
122
+ extern void* _mi_page_malloc_zeroed(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept {
123
+ return _mi_page_malloc_zero(heap,page,size,true);
124
+ }
125
+
126
+ #if MI_GUARDED
127
+ mi_decl_restrict void* _mi_heap_malloc_guarded(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept;
128
+ #endif
129
+
130
+ static inline mi_decl_restrict void* mi_heap_malloc_small_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept {
131
+ mi_assert(heap != NULL);
132
+ mi_assert(size <= MI_SMALL_SIZE_MAX);
133
+ #if MI_DEBUG
134
+ const uintptr_t tid = _mi_thread_id();
135
+ mi_assert(heap->thread_id == 0 || heap->thread_id == tid); // heaps are thread local
136
+ #endif
137
+ #if (MI_PADDING || MI_GUARDED)
138
+ if (size == 0) { size = sizeof(void*); }
139
+ #endif
140
+ #if MI_GUARDED
141
+ if (mi_heap_malloc_use_guarded(heap,size)) {
142
+ return _mi_heap_malloc_guarded(heap, size, zero);
143
+ }
144
+ #endif
145
+
146
+ // get page in constant time, and allocate from it
147
+ mi_page_t* page = _mi_heap_get_free_small_page(heap, size + MI_PADDING_SIZE);
148
+ void* const p = _mi_page_malloc_zero(heap, page, size + MI_PADDING_SIZE, zero);
149
+ mi_track_malloc(p,size,zero);
150
+
151
+ #if MI_DEBUG>3
152
+ if (p != NULL && zero) {
153
+ mi_assert_expensive(mi_mem_is_zero(p, size));
154
+ }
155
+ #endif
156
+ return p;
157
+ }
158
+
159
+ // allocate a small block
160
+ mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept {
161
+ return mi_heap_malloc_small_zero(heap, size, false);
162
+ }
163
+
164
+ mi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept {
165
+ return mi_heap_malloc_small(mi_prim_get_default_heap(), size);
166
+ }
167
+
168
+ // The main allocation function
169
+ extern inline void* _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept {
170
+ // fast path for small objects
171
+ if mi_likely(size <= MI_SMALL_SIZE_MAX) {
172
+ mi_assert_internal(huge_alignment == 0);
173
+ return mi_heap_malloc_small_zero(heap, size, zero);
174
+ }
175
+ #if MI_GUARDED
176
+ else if (huge_alignment==0 && mi_heap_malloc_use_guarded(heap,size)) {
177
+ return _mi_heap_malloc_guarded(heap, size, zero);
178
+ }
179
+ #endif
180
+ else {
181
+ // regular allocation
182
+ mi_assert(heap!=NULL);
183
+ mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id()); // heaps are thread local
184
+ void* const p = _mi_malloc_generic(heap, size + MI_PADDING_SIZE, zero, huge_alignment); // note: size can overflow but it is detected in malloc_generic
185
+ mi_track_malloc(p,size,zero);
186
+
187
+ #if MI_DEBUG>3
188
+ if (p != NULL && zero) {
189
+ mi_assert_expensive(mi_mem_is_zero(p, size));
190
+ }
191
+ #endif
192
+ return p;
193
+ }
194
+ }
195
+
196
+ extern inline void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept {
197
+ return _mi_heap_malloc_zero_ex(heap, size, zero, 0);
198
+ }
199
+
200
+ mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {
201
+ return _mi_heap_malloc_zero(heap, size, false);
202
+ }
203
+
204
+ mi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept {
205
+ return mi_heap_malloc(mi_prim_get_default_heap(), size);
206
+ }
207
+
208
+ // zero initialized small block
209
+ mi_decl_nodiscard mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept {
210
+ return mi_heap_malloc_small_zero(mi_prim_get_default_heap(), size, true);
211
+ }
212
+
213
+ mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept {
214
+ return _mi_heap_malloc_zero(heap, size, true);
215
+ }
216
+
217
+ mi_decl_nodiscard mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept {
218
+ return mi_heap_zalloc(mi_prim_get_default_heap(),size);
219
+ }
220
+
221
+
222
+ mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {
223
+ size_t total;
224
+ if (mi_count_size_overflow(count,size,&total)) return NULL;
225
+ return mi_heap_zalloc(heap,total);
226
+ }
227
+
228
+ mi_decl_nodiscard mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept {
229
+ return mi_heap_calloc(mi_prim_get_default_heap(),count,size);
230
+ }
231
+
232
+ // Uninitialized `calloc`
233
+ mi_decl_nodiscard extern mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept {
234
+ size_t total;
235
+ if (mi_count_size_overflow(count, size, &total)) return NULL;
236
+ return mi_heap_malloc(heap, total);
237
+ }
238
+
239
+ mi_decl_nodiscard mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept {
240
+ return mi_heap_mallocn(mi_prim_get_default_heap(),count,size);
241
+ }
242
+
243
+ // Expand (or shrink) in place (or fail)
244
+ void* mi_expand(void* p, size_t newsize) mi_attr_noexcept {
245
+ #if MI_PADDING
246
+ // we do not shrink/expand with padding enabled
247
+ MI_UNUSED(p); MI_UNUSED(newsize);
248
+ return NULL;
249
+ #else
250
+ if (p == NULL) return NULL;
251
+ const size_t size = _mi_usable_size(p,"mi_expand");
252
+ if (newsize > size) return NULL;
253
+ return p; // it fits
254
+ #endif
255
+ }
256
+
257
+ void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept {
258
+ // if p == NULL then behave as malloc.
259
+ // else if size == 0 then reallocate to a zero-sized block (and don't return NULL, just as mi_malloc(0)).
260
+ // (this means that returning NULL always indicates an error, and `p` will not have been freed in that case.)
261
+ const size_t size = _mi_usable_size(p,"mi_realloc"); // also works if p == NULL (with size 0)
262
+ if mi_unlikely(newsize <= size && newsize >= (size / 2) && newsize > 0) { // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0)
263
+ mi_assert_internal(p!=NULL);
264
+ // todo: do not track as the usable size is still the same in the free; adjust potential padding?
265
+ // mi_track_resize(p,size,newsize)
266
+ // if (newsize < size) { mi_track_mem_noaccess((uint8_t*)p + newsize, size - newsize); }
267
+ return p; // reallocation still fits and not more than 50% waste
268
+ }
269
+ void* newp = mi_heap_malloc(heap,newsize);
270
+ if mi_likely(newp != NULL) {
271
+ if (zero && newsize > size) {
272
+ // also set last word in the previous allocation to zero to ensure any padding is zero-initialized
273
+ const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0);
274
+ _mi_memzero((uint8_t*)newp + start, newsize - start);
275
+ }
276
+ else if (newsize == 0) {
277
+ ((uint8_t*)newp)[0] = 0; // work around for applications that expect zero-reallocation to be zero initialized (issue #725)
278
+ }
279
+ if mi_likely(p != NULL) {
280
+ const size_t copysize = (newsize > size ? size : newsize);
281
+ mi_track_mem_defined(p,copysize); // _mi_useable_size may be too large for byte precise memory tracking..
282
+ _mi_memcpy(newp, p, copysize);
283
+ mi_free(p); // only free the original pointer if successful
284
+ }
285
+ }
286
+ return newp;
287
+ }
288
+
289
+ mi_decl_nodiscard void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
290
+ return _mi_heap_realloc_zero(heap, p, newsize, false);
291
+ }
292
+
293
+ mi_decl_nodiscard void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {
294
+ size_t total;
295
+ if (mi_count_size_overflow(count, size, &total)) return NULL;
296
+ return mi_heap_realloc(heap, p, total);
297
+ }
298
+
299
+
300
+ // Reallocate but free `p` on errors
301
+ mi_decl_nodiscard void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
302
+ void* newp = mi_heap_realloc(heap, p, newsize);
303
+ if (newp==NULL && p!=NULL) mi_free(p);
304
+ return newp;
305
+ }
306
+
307
+ mi_decl_nodiscard void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept {
308
+ return _mi_heap_realloc_zero(heap, p, newsize, true);
309
+ }
310
+
311
+ mi_decl_nodiscard void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept {
312
+ size_t total;
313
+ if (mi_count_size_overflow(count, size, &total)) return NULL;
314
+ return mi_heap_rezalloc(heap, p, total);
315
+ }
316
+
317
+
318
+ mi_decl_nodiscard void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept {
319
+ return mi_heap_realloc(mi_prim_get_default_heap(),p,newsize);
320
+ }
321
+
322
+ mi_decl_nodiscard void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept {
323
+ return mi_heap_reallocn(mi_prim_get_default_heap(),p,count,size);
324
+ }
325
+
326
+ // Reallocate but free `p` on errors
327
+ mi_decl_nodiscard void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept {
328
+ return mi_heap_reallocf(mi_prim_get_default_heap(),p,newsize);
329
+ }
330
+
331
+ mi_decl_nodiscard void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept {
332
+ return mi_heap_rezalloc(mi_prim_get_default_heap(), p, newsize);
333
+ }
334
+
335
+ mi_decl_nodiscard void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept {
336
+ return mi_heap_recalloc(mi_prim_get_default_heap(), p, count, size);
337
+ }
338
+
339
+
340
+
341
+ // ------------------------------------------------------
342
+ // strdup, strndup, and realpath
343
+ // ------------------------------------------------------
344
+
345
+ // `strdup` using mi_malloc
346
+ mi_decl_nodiscard mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept {
347
+ if (s == NULL) return NULL;
348
+ size_t len = _mi_strlen(s);
349
+ char* t = (char*)mi_heap_malloc(heap,len+1);
350
+ if (t == NULL) return NULL;
351
+ _mi_memcpy(t, s, len);
352
+ t[len] = 0;
353
+ return t;
354
+ }
355
+
356
+ mi_decl_nodiscard mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept {
357
+ return mi_heap_strdup(mi_prim_get_default_heap(), s);
358
+ }
359
+
360
+ // `strndup` using mi_malloc
361
+ mi_decl_nodiscard mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept {
362
+ if (s == NULL) return NULL;
363
+ const size_t len = _mi_strnlen(s,n); // len <= n
364
+ char* t = (char*)mi_heap_malloc(heap, len+1);
365
+ if (t == NULL) return NULL;
366
+ _mi_memcpy(t, s, len);
367
+ t[len] = 0;
368
+ return t;
369
+ }
370
+
371
+ mi_decl_nodiscard mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept {
372
+ return mi_heap_strndup(mi_prim_get_default_heap(),s,n);
373
+ }
374
+
375
+ #ifndef __wasi__
376
+ // `realpath` using mi_malloc
377
+ #ifdef _WIN32
378
+ #ifndef PATH_MAX
379
+ #define PATH_MAX MAX_PATH
380
+ #endif
381
+
382
+ mi_decl_nodiscard mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept {
383
+ // todo: use GetFullPathNameW to allow longer file names
384
+ char buf[PATH_MAX];
385
+ DWORD res = GetFullPathNameA(fname, PATH_MAX, (resolved_name == NULL ? buf : resolved_name), NULL);
386
+ if (res == 0) {
387
+ errno = GetLastError(); return NULL;
388
+ }
389
+ else if (res > PATH_MAX) {
390
+ errno = EINVAL; return NULL;
391
+ }
392
+ else if (resolved_name != NULL) {
393
+ return resolved_name;
394
+ }
395
+ else {
396
+ return mi_heap_strndup(heap, buf, PATH_MAX);
397
+ }
398
+ }
399
+ #else
400
+ /*
401
+ #include <unistd.h> // pathconf
402
+ static size_t mi_path_max(void) {
403
+ static size_t path_max = 0;
404
+ if (path_max <= 0) {
405
+ long m = pathconf("/",_PC_PATH_MAX);
406
+ if (m <= 0) path_max = 4096; // guess
407
+ else if (m < 256) path_max = 256; // at least 256
408
+ else path_max = m;
409
+ }
410
+ return path_max;
411
+ }
412
+ */
413
+ char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept {
414
+ if (resolved_name != NULL) {
415
+ return realpath(fname,resolved_name);
416
+ }
417
+ else {
418
+ char* rname = realpath(fname, NULL);
419
+ if (rname == NULL) return NULL;
420
+ char* result = mi_heap_strdup(heap, rname);
421
+ mi_cfree(rname); // use checked free (which may be redirected to our free but that's ok)
422
+ // note: with ASAN realpath is intercepted and mi_cfree may leak the returned pointer :-(
423
+ return result;
424
+ }
425
+ /*
426
+ const size_t n = mi_path_max();
427
+ char* buf = (char*)mi_malloc(n+1);
428
+ if (buf == NULL) {
429
+ errno = ENOMEM;
430
+ return NULL;
431
+ }
432
+ char* rname = realpath(fname,buf);
433
+ char* result = mi_heap_strndup(heap,rname,n); // ok if `rname==NULL`
434
+ mi_free(buf);
435
+ return result;
436
+ }
437
+ */
438
+ }
439
+ #endif
440
+
441
+ mi_decl_nodiscard mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept {
442
+ return mi_heap_realpath(mi_prim_get_default_heap(),fname,resolved_name);
443
+ }
444
+ #endif
445
+
446
+ /*-------------------------------------------------------
447
+ C++ new and new_aligned
448
+ The standard requires calling into `get_new_handler` and
449
+ throwing the bad_alloc exception on failure. If we compile
450
+ with a C++ compiler we can implement this precisely. If we
451
+ use a C compiler we cannot throw a `bad_alloc` exception
452
+ but we call `exit` instead (i.e. not returning).
453
+ -------------------------------------------------------*/
454
+
455
+ #ifdef __cplusplus
456
+ #include <new>
457
+ static bool mi_try_new_handler(bool nothrow) {
458
+ #if defined(_MSC_VER) || (__cplusplus >= 201103L)
459
+ std::new_handler h = std::get_new_handler();
460
+ #else
461
+ std::new_handler h = std::set_new_handler();
462
+ std::set_new_handler(h);
463
+ #endif
464
+ if (h==NULL) {
465
+ _mi_error_message(ENOMEM, "out of memory in 'new'");
466
+ #if defined(_CPPUNWIND) || defined(__cpp_exceptions) // exceptions are not always enabled
467
+ if (!nothrow) {
468
+ throw std::bad_alloc();
469
+ }
470
+ #else
471
+ MI_UNUSED(nothrow);
472
+ #endif
473
+ return false;
474
+ }
475
+ else {
476
+ h();
477
+ return true;
478
+ }
479
+ }
480
+ #else
481
+ typedef void (*std_new_handler_t)(void);
482
+
483
+ #if (defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER))) // exclude clang-cl, see issue #631
484
+ std_new_handler_t __attribute__((weak)) _ZSt15get_new_handlerv(void) {
485
+ return NULL;
486
+ }
487
+ static std_new_handler_t mi_get_new_handler(void) {
488
+ return _ZSt15get_new_handlerv();
489
+ }
490
+ #else
491
+ // note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`.
492
+ static std_new_handler_t mi_get_new_handler() {
493
+ return NULL;
494
+ }
495
+ #endif
496
+
497
+ static bool mi_try_new_handler(bool nothrow) {
498
+ std_new_handler_t h = mi_get_new_handler();
499
+ if (h==NULL) {
500
+ _mi_error_message(ENOMEM, "out of memory in 'new'");
501
+ if (!nothrow) {
502
+ abort(); // cannot throw in plain C, use abort
503
+ }
504
+ return false;
505
+ }
506
+ else {
507
+ h();
508
+ return true;
509
+ }
510
+ }
511
+ #endif
512
+
513
+ mi_decl_export mi_decl_noinline void* mi_heap_try_new(mi_heap_t* heap, size_t size, bool nothrow ) {
514
+ void* p = NULL;
515
+ while(p == NULL && mi_try_new_handler(nothrow)) {
516
+ p = mi_heap_malloc(heap,size);
517
+ }
518
+ return p;
519
+ }
520
+
521
+ static mi_decl_noinline void* mi_try_new(size_t size, bool nothrow) {
522
+ return mi_heap_try_new(mi_prim_get_default_heap(), size, nothrow);
523
+ }
524
+
525
+
526
+ mi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) {
527
+ void* p = mi_heap_malloc(heap,size);
528
+ if mi_unlikely(p == NULL) return mi_heap_try_new(heap, size, false);
529
+ return p;
530
+ }
531
+
532
+ mi_decl_nodiscard mi_decl_restrict void* mi_new(size_t size) {
533
+ return mi_heap_alloc_new(mi_prim_get_default_heap(), size);
534
+ }
535
+
536
+
537
+ mi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) {
538
+ size_t total;
539
+ if mi_unlikely(mi_count_size_overflow(count, size, &total)) {
540
+ mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc
541
+ return NULL;
542
+ }
543
+ else {
544
+ return mi_heap_alloc_new(heap,total);
545
+ }
546
+ }
547
+
548
+ mi_decl_nodiscard mi_decl_restrict void* mi_new_n(size_t count, size_t size) {
549
+ return mi_heap_alloc_new_n(mi_prim_get_default_heap(), count, size);
550
+ }
551
+
552
+
553
+ mi_decl_nodiscard mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept {
554
+ void* p = mi_malloc(size);
555
+ if mi_unlikely(p == NULL) return mi_try_new(size, true);
556
+ return p;
557
+ }
558
+
559
+ mi_decl_nodiscard mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) {
560
+ void* p;
561
+ do {
562
+ p = mi_malloc_aligned(size, alignment);
563
+ }
564
+ while(p == NULL && mi_try_new_handler(false));
565
+ return p;
566
+ }
567
+
568
+ mi_decl_nodiscard mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept {
569
+ void* p;
570
+ do {
571
+ p = mi_malloc_aligned(size, alignment);
572
+ }
573
+ while(p == NULL && mi_try_new_handler(true));
574
+ return p;
575
+ }
576
+
577
+ mi_decl_nodiscard void* mi_new_realloc(void* p, size_t newsize) {
578
+ void* q;
579
+ do {
580
+ q = mi_realloc(p, newsize);
581
+ } while (q == NULL && mi_try_new_handler(false));
582
+ return q;
583
+ }
584
+
585
+ mi_decl_nodiscard void* mi_new_reallocn(void* p, size_t newcount, size_t size) {
586
+ size_t total;
587
+ if mi_unlikely(mi_count_size_overflow(newcount, size, &total)) {
588
+ mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc
589
+ return NULL;
590
+ }
591
+ else {
592
+ return mi_new_realloc(p, total);
593
+ }
594
+ }
595
+
596
+ #if MI_GUARDED
597
+ // We always allocate a guarded allocation at an offset (`mi_page_has_aligned` will be true).
598
+ // We then set the first word of the block to `0` for regular offset aligned allocations (in `alloc-aligned.c`)
599
+ // and the first word to `~0` for guarded allocations to have a correct `mi_usable_size`
600
+
601
+ static void* mi_block_ptr_set_guarded(mi_block_t* block, size_t obj_size) {
602
+ // TODO: we can still make padding work by moving it out of the guard page area
603
+ mi_page_t* const page = _mi_ptr_page(block);
604
+ mi_page_set_has_aligned(page, true);
605
+ block->next = MI_BLOCK_TAG_GUARDED;
606
+
607
+ // set guard page at the end of the block
608
+ mi_segment_t* const segment = _mi_page_segment(page);
609
+ const size_t block_size = mi_page_block_size(page); // must use `block_size` to match `mi_free_local`
610
+ const size_t os_page_size = _mi_os_page_size();
611
+ mi_assert_internal(block_size >= obj_size + os_page_size + sizeof(mi_block_t));
612
+ if (block_size < obj_size + os_page_size + sizeof(mi_block_t)) {
613
+ // should never happen
614
+ mi_free(block);
615
+ return NULL;
616
+ }
617
+ uint8_t* guard_page = (uint8_t*)block + block_size - os_page_size;
618
+ mi_assert_internal(_mi_is_aligned(guard_page, os_page_size));
619
+ if (segment->allow_decommit && _mi_is_aligned(guard_page, os_page_size)) {
620
+ _mi_os_protect(guard_page, os_page_size);
621
+ }
622
+ else {
623
+ _mi_warning_message("unable to set a guard page behind an object due to pinned memory (large OS pages?) (object %p of size %zu)\n", block, block_size);
624
+ }
625
+
626
+ // align pointer just in front of the guard page
627
+ size_t offset = block_size - os_page_size - obj_size;
628
+ mi_assert_internal(offset > sizeof(mi_block_t));
629
+ if (offset > MI_BLOCK_ALIGNMENT_MAX) {
630
+ // give up to place it right in front of the guard page if the offset is too large for unalignment
631
+ offset = MI_BLOCK_ALIGNMENT_MAX;
632
+ }
633
+ void* p = (uint8_t*)block + offset;
634
+ mi_track_align(block, p, offset, obj_size);
635
+ mi_track_mem_defined(block, sizeof(mi_block_t));
636
+ return p;
637
+ }
638
+
639
+ mi_decl_restrict void* _mi_heap_malloc_guarded(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept
640
+ {
641
+ #if defined(MI_PADDING_SIZE)
642
+ mi_assert(MI_PADDING_SIZE==0);
643
+ #endif
644
+ // allocate multiple of page size ending in a guard page
645
+ // ensure minimal alignment requirement?
646
+ const size_t os_page_size = _mi_os_page_size();
647
+ const size_t obj_size = (mi_option_is_enabled(mi_option_guarded_precise) ? size : _mi_align_up(size, MI_MAX_ALIGN_SIZE));
648
+ const size_t bsize = _mi_align_up(_mi_align_up(obj_size, MI_MAX_ALIGN_SIZE) + sizeof(mi_block_t), MI_MAX_ALIGN_SIZE);
649
+ const size_t req_size = _mi_align_up(bsize + os_page_size, os_page_size);
650
+ mi_block_t* const block = (mi_block_t*)_mi_malloc_generic(heap, req_size, zero, 0 /* huge_alignment */);
651
+ if (block==NULL) return NULL;
652
+ void* const p = mi_block_ptr_set_guarded(block, obj_size);
653
+
654
+ // stats
655
+ mi_track_malloc(p, size, zero);
656
+ if (p != NULL) {
657
+ if (!mi_heap_is_initialized(heap)) { heap = mi_prim_get_default_heap(); }
658
+ #if MI_STAT>1
659
+ mi_heap_stat_adjust_decrease(heap, malloc_requested, req_size);
660
+ mi_heap_stat_increase(heap, malloc_requested, size);
661
+ #endif
662
+ _mi_stat_counter_increase(&heap->tld->stats.malloc_guarded_count, 1);
663
+ }
664
+ #if MI_DEBUG>3
665
+ if (p != NULL && zero) {
666
+ mi_assert_expensive(mi_mem_is_zero(p, size));
667
+ }
668
+ #endif
669
+ return p;
670
+ }
671
+ #endif
672
+
673
+ // ------------------------------------------------------
674
+ // ensure explicit external inline definitions are emitted!
675
+ // ------------------------------------------------------
676
+
677
+ #ifdef __cplusplus
678
+ void* _mi_externs[] = {
679
+ (void*)&_mi_page_malloc,
680
+ (void*)&_mi_page_malloc_zero,
681
+ (void*)&_mi_heap_malloc_zero,
682
+ (void*)&_mi_heap_malloc_zero_ex,
683
+ (void*)&mi_malloc,
684
+ (void*)&mi_malloc_small,
685
+ (void*)&mi_zalloc_small,
686
+ (void*)&mi_heap_malloc,
687
+ (void*)&mi_heap_zalloc,
688
+ (void*)&mi_heap_malloc_small,
689
+ // (void*)&mi_heap_alloc_new,
690
+ // (void*)&mi_heap_alloc_new_n
691
+ };
692
+ #endif