@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,572 @@
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
+ #if !defined(MI_IN_ALLOC_C)
8
+ #error "this file should be included from 'alloc.c' (so aliases can work from alloc-override)"
9
+ // add includes help an IDE
10
+ #include "mimalloc.h"
11
+ #include "mimalloc/internal.h"
12
+ #include "mimalloc/prim.h" // _mi_prim_thread_id()
13
+ #endif
14
+
15
+ // forward declarations
16
+ static void mi_check_padding(const mi_page_t* page, const mi_block_t* block);
17
+ static bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block);
18
+ static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block);
19
+ static void mi_stat_free(const mi_page_t* page, const mi_block_t* block);
20
+
21
+
22
+ // ------------------------------------------------------
23
+ // Free
24
+ // ------------------------------------------------------
25
+
26
+ // forward declaration of multi-threaded free (`_mt`) (or free in huge block if compiled with MI_HUGE_PAGE_ABANDON)
27
+ static mi_decl_noinline void mi_free_block_mt(mi_page_t* page, mi_segment_t* segment, mi_block_t* block);
28
+
29
+ // regular free of a (thread local) block pointer
30
+ // fast path written carefully to prevent spilling on the stack
31
+ static inline void mi_free_block_local(mi_page_t* page, mi_block_t* block, bool track_stats, bool check_full)
32
+ {
33
+ // checks
34
+ if mi_unlikely(mi_check_is_double_free(page, block)) return;
35
+ mi_check_padding(page, block);
36
+ if (track_stats) { mi_stat_free(page, block); }
37
+ #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN && !MI_GUARDED
38
+ if (!mi_page_is_huge(page)) { // huge page content may be already decommitted
39
+ memset(block, MI_DEBUG_FREED, mi_page_block_size(page));
40
+ }
41
+ #endif
42
+ if (track_stats) { mi_track_free_size(block, mi_page_usable_size_of(page, block)); } // faster then mi_usable_size as we already know the page and that p is unaligned
43
+
44
+ // actual free: push on the local free list
45
+ mi_block_set_next(page, block, page->local_free);
46
+ page->local_free = block;
47
+ if mi_unlikely(--page->used == 0) {
48
+ _mi_page_retire(page);
49
+ }
50
+ else if mi_unlikely(check_full && mi_page_is_in_full(page)) {
51
+ _mi_page_unfull(page);
52
+ }
53
+ }
54
+
55
+ // Adjust a block that was allocated aligned, to the actual start of the block in the page.
56
+ // note: this can be called from `mi_free_generic_mt` where a non-owning thread accesses the
57
+ // `page_start` and `block_size` fields; however these are constant and the page won't be
58
+ // deallocated (as the block we are freeing keeps it alive) and thus safe to read concurrently.
59
+ mi_block_t* _mi_page_ptr_unalign(const mi_page_t* page, const void* p) {
60
+ mi_assert_internal(page!=NULL && p!=NULL);
61
+
62
+ size_t diff = (uint8_t*)p - page->page_start;
63
+ size_t adjust;
64
+ if mi_likely(page->block_size_shift != 0) {
65
+ adjust = diff & (((size_t)1 << page->block_size_shift) - 1);
66
+ }
67
+ else {
68
+ adjust = diff % mi_page_block_size(page);
69
+ }
70
+
71
+ return (mi_block_t*)((uintptr_t)p - adjust);
72
+ }
73
+
74
+ // forward declaration for a MI_GUARDED build
75
+ #if MI_GUARDED
76
+ static void mi_block_unguard(mi_page_t* page, mi_block_t* block, void* p); // forward declaration
77
+ static inline void mi_block_check_unguard(mi_page_t* page, mi_block_t* block, void* p) {
78
+ if (mi_block_ptr_is_guarded(block, p)) { mi_block_unguard(page, block, p); }
79
+ }
80
+ #else
81
+ static inline void mi_block_check_unguard(mi_page_t* page, mi_block_t* block, void* p) {
82
+ MI_UNUSED(page); MI_UNUSED(block); MI_UNUSED(p);
83
+ }
84
+ #endif
85
+
86
+ // free a local pointer (page parameter comes first for better codegen)
87
+ static void mi_decl_noinline mi_free_generic_local(mi_page_t* page, mi_segment_t* segment, void* p) mi_attr_noexcept {
88
+ MI_UNUSED(segment);
89
+ mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(page, p) : (mi_block_t*)p);
90
+ mi_block_check_unguard(page, block, p);
91
+ mi_free_block_local(page, block, true /* track stats */, true /* check for a full page */);
92
+ }
93
+
94
+ // free a pointer owned by another thread (page parameter comes first for better codegen)
95
+ static void mi_decl_noinline mi_free_generic_mt(mi_page_t* page, mi_segment_t* segment, void* p) mi_attr_noexcept {
96
+ mi_block_t* const block = _mi_page_ptr_unalign(page, p); // don't check `has_aligned` flag to avoid a race (issue #865)
97
+ mi_block_check_unguard(page, block, p);
98
+ mi_free_block_mt(page, segment, block);
99
+ }
100
+
101
+ // generic free (for runtime integration)
102
+ void mi_decl_noinline _mi_free_generic(mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept {
103
+ if (is_local) mi_free_generic_local(page,segment,p);
104
+ else mi_free_generic_mt(page,segment,p);
105
+ }
106
+
107
+ // Get the segment data belonging to a pointer
108
+ // This is just a single `and` in release mode but does further checks in debug mode
109
+ // (and secure mode) to see if this was a valid pointer.
110
+ static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg)
111
+ {
112
+ MI_UNUSED(msg);
113
+
114
+ #if (MI_DEBUG>0)
115
+ if mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0 && !mi_option_is_enabled(mi_option_guarded_precise)) {
116
+ _mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p);
117
+ return NULL;
118
+ }
119
+ #endif
120
+
121
+ mi_segment_t* const segment = _mi_ptr_segment(p);
122
+ if mi_unlikely(segment==NULL) return segment;
123
+
124
+ #if (MI_DEBUG>0)
125
+ if mi_unlikely(!mi_is_in_heap_region(p)) {
126
+ #if (MI_INTPTR_SIZE == 8 && defined(__linux__))
127
+ if (((uintptr_t)p >> 40) != 0x7F) { // linux tends to align large blocks above 0x7F000000000 (issue #640)
128
+ #else
129
+ {
130
+ #endif
131
+ _mi_warning_message("%s: pointer might not point to a valid heap region: %p\n"
132
+ "(this may still be a valid very large allocation (over 64MiB))\n", msg, p);
133
+ if mi_likely(_mi_ptr_cookie(segment) == segment->cookie) {
134
+ _mi_warning_message("(yes, the previous pointer %p was valid after all)\n", p);
135
+ }
136
+ }
137
+ }
138
+ #endif
139
+ #if (MI_DEBUG>0 || MI_SECURE>=4)
140
+ if mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie) {
141
+ _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", msg, p);
142
+ return NULL;
143
+ }
144
+ #endif
145
+
146
+ return segment;
147
+ }
148
+
149
+ // Free a block
150
+ // Fast path written carefully to prevent register spilling on the stack
151
+ void mi_free(void* p) mi_attr_noexcept
152
+ {
153
+ mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free");
154
+ if mi_unlikely(segment==NULL) return;
155
+
156
+ const bool is_local = (_mi_prim_thread_id() == mi_atomic_load_relaxed(&segment->thread_id));
157
+ mi_page_t* const page = _mi_segment_page_of(segment, p);
158
+
159
+ if mi_likely(is_local) { // thread-local free?
160
+ if mi_likely(page->flags.full_aligned == 0) { // and it is not a full page (full pages need to move from the full bin), nor has aligned blocks (aligned blocks need to be unaligned)
161
+ // thread-local, aligned, and not a full page
162
+ mi_block_t* const block = (mi_block_t*)p;
163
+ mi_free_block_local(page, block, true /* track stats */, false /* no need to check if the page is full */);
164
+ }
165
+ else {
166
+ // page is full or contains (inner) aligned blocks; use generic path
167
+ mi_free_generic_local(page, segment, p);
168
+ }
169
+ }
170
+ else {
171
+ // not thread-local; use generic path
172
+ mi_free_generic_mt(page, segment, p);
173
+ }
174
+ }
175
+
176
+ // return true if successful
177
+ bool _mi_free_delayed_block(mi_block_t* block) {
178
+ // get segment and page
179
+ mi_assert_internal(block!=NULL);
180
+ const mi_segment_t* const segment = _mi_ptr_segment(block);
181
+ mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);
182
+ mi_assert_internal(_mi_thread_id() == segment->thread_id);
183
+ mi_page_t* const page = _mi_segment_page_of(segment, block);
184
+
185
+ // Clear the no-delayed flag so delayed freeing is used again for this page.
186
+ // This must be done before collecting the free lists on this page -- otherwise
187
+ // some blocks may end up in the page `thread_free` list with no blocks in the
188
+ // heap `thread_delayed_free` list which may cause the page to be never freed!
189
+ // (it would only be freed if we happen to scan it in `mi_page_queue_find_free_ex`)
190
+ if (!_mi_page_try_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */)) {
191
+ return false;
192
+ }
193
+
194
+ // collect all other non-local frees (move from `thread_free` to `free`) to ensure up-to-date `used` count
195
+ _mi_page_free_collect(page, false);
196
+
197
+ // and free the block (possibly freeing the page as well since `used` is updated)
198
+ mi_free_block_local(page, block, false /* stats have already been adjusted */, true /* check for a full page */);
199
+ return true;
200
+ }
201
+
202
+ // ------------------------------------------------------
203
+ // Multi-threaded Free (`_mt`)
204
+ // ------------------------------------------------------
205
+
206
+ // Push a block that is owned by another thread on its page-local thread free
207
+ // list or it's heap delayed free list. Such blocks are later collected by
208
+ // the owning thread in `_mi_free_delayed_block`.
209
+ static void mi_decl_noinline mi_free_block_delayed_mt( mi_page_t* page, mi_block_t* block )
210
+ {
211
+ // Try to put the block on either the page-local thread free list,
212
+ // or the heap delayed free list (if this is the first non-local free in that page)
213
+ mi_thread_free_t tfreex;
214
+ bool use_delayed;
215
+ mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free);
216
+ do {
217
+ use_delayed = (mi_tf_delayed(tfree) == MI_USE_DELAYED_FREE);
218
+ if mi_unlikely(use_delayed) {
219
+ // unlikely: this only happens on the first concurrent free in a page that is in the full list
220
+ tfreex = mi_tf_set_delayed(tfree,MI_DELAYED_FREEING);
221
+ }
222
+ else {
223
+ // usual: directly add to page thread_free list
224
+ mi_block_set_next(page, block, mi_tf_block(tfree));
225
+ tfreex = mi_tf_set_block(tfree,block);
226
+ }
227
+ } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));
228
+
229
+ // If this was the first non-local free, we need to push it on the heap delayed free list instead
230
+ if mi_unlikely(use_delayed) {
231
+ // racy read on `heap`, but ok because MI_DELAYED_FREEING is set (see `mi_heap_delete` and `mi_heap_collect_abandon`)
232
+ mi_heap_t* const heap = (mi_heap_t*)(mi_atomic_load_acquire(&page->xheap)); //mi_page_heap(page);
233
+ mi_assert_internal(heap != NULL);
234
+ if (heap != NULL) {
235
+ // add to the delayed free list of this heap. (do this atomically as the lock only protects heap memory validity)
236
+ mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free);
237
+ do {
238
+ mi_block_set_nextx(heap,block,dfree, heap->keys);
239
+ } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block));
240
+ }
241
+
242
+ // and reset the MI_DELAYED_FREEING flag
243
+ tfree = mi_atomic_load_relaxed(&page->xthread_free);
244
+ do {
245
+ tfreex = tfree;
246
+ mi_assert_internal(mi_tf_delayed(tfree) == MI_DELAYED_FREEING);
247
+ tfreex = mi_tf_set_delayed(tfree,MI_NO_DELAYED_FREE);
248
+ } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex));
249
+ }
250
+ }
251
+
252
+ // Multi-threaded free (`_mt`) (or free in huge block if compiled with MI_HUGE_PAGE_ABANDON)
253
+ static void mi_decl_noinline mi_free_block_mt(mi_page_t* page, mi_segment_t* segment, mi_block_t* block)
254
+ {
255
+ // first see if the segment was abandoned and if we can reclaim it into our thread
256
+ if (_mi_option_get_fast(mi_option_abandoned_reclaim_on_free) != 0 &&
257
+ #if MI_HUGE_PAGE_ABANDON
258
+ segment->page_kind != MI_PAGE_HUGE &&
259
+ #endif
260
+ mi_atomic_load_relaxed(&segment->thread_id) == 0 && // segment is abandoned?
261
+ mi_prim_get_default_heap() != (mi_heap_t*)&_mi_heap_empty) // and we did not already exit this thread (without this check, a fresh heap will be initalized (issue #944))
262
+ {
263
+ // the segment is abandoned, try to reclaim it into our heap
264
+ if (_mi_segment_attempt_reclaim(mi_heap_get_default(), segment)) {
265
+ mi_assert_internal(_mi_thread_id() == mi_atomic_load_relaxed(&segment->thread_id));
266
+ mi_assert_internal(mi_heap_get_default()->tld->segments.subproc == segment->subproc);
267
+ mi_free(block); // recursively free as now it will be a local free in our heap
268
+ return;
269
+ }
270
+ }
271
+
272
+ // The padding check may access the non-thread-owned page for the key values.
273
+ // that is safe as these are constant and the page won't be freed (as the block is not freed yet).
274
+ mi_check_padding(page, block);
275
+
276
+ // adjust stats (after padding check and potentially recursive `mi_free` above)
277
+ mi_stat_free(page, block); // stat_free may access the padding
278
+ mi_track_free_size(block, mi_page_usable_size_of(page,block));
279
+
280
+ // for small size, ensure we can fit the delayed thread pointers without triggering overflow detection
281
+ _mi_padding_shrink(page, block, sizeof(mi_block_t));
282
+
283
+ if (segment->kind == MI_SEGMENT_HUGE) {
284
+ #if MI_HUGE_PAGE_ABANDON
285
+ // huge page segments are always abandoned and can be freed immediately
286
+ _mi_segment_huge_page_free(segment, page, block);
287
+ return;
288
+ #else
289
+ // huge pages are special as they occupy the entire segment
290
+ // as these are large we reset the memory occupied by the page so it is available to other threads
291
+ // (as the owning thread needs to actually free the memory later).
292
+ _mi_segment_huge_page_reset(segment, page, block);
293
+ #endif
294
+ }
295
+ else {
296
+ #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN // note: when tracking, cannot use mi_usable_size with multi-threading
297
+ memset(block, MI_DEBUG_FREED, mi_usable_size(block));
298
+ #endif
299
+ }
300
+
301
+ // and finally free the actual block by pushing it on the owning heap
302
+ // thread_delayed free list (or heap delayed free list)
303
+ mi_free_block_delayed_mt(page,block);
304
+ }
305
+
306
+
307
+ // ------------------------------------------------------
308
+ // Usable size
309
+ // ------------------------------------------------------
310
+
311
+ // Bytes available in a block
312
+ static size_t mi_decl_noinline mi_page_usable_aligned_size_of(const mi_page_t* page, const void* p) mi_attr_noexcept {
313
+ const mi_block_t* block = _mi_page_ptr_unalign(page, p);
314
+ const size_t size = mi_page_usable_size_of(page, block);
315
+ const ptrdiff_t adjust = (uint8_t*)p - (uint8_t*)block;
316
+ mi_assert_internal(adjust >= 0 && (size_t)adjust <= size);
317
+ const size_t aligned_size = (size - adjust);
318
+ #if MI_GUARDED
319
+ if (mi_block_ptr_is_guarded(block, p)) {
320
+ return aligned_size - _mi_os_page_size();
321
+ }
322
+ #endif
323
+ return aligned_size;
324
+ }
325
+
326
+ static inline size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept {
327
+ const mi_segment_t* const segment = mi_checked_ptr_segment(p, msg);
328
+ if mi_unlikely(segment==NULL) return 0;
329
+ const mi_page_t* const page = _mi_segment_page_of(segment, p);
330
+ if mi_likely(!mi_page_has_aligned(page)) {
331
+ const mi_block_t* block = (const mi_block_t*)p;
332
+ return mi_page_usable_size_of(page, block);
333
+ }
334
+ else {
335
+ // split out to separate routine for improved code generation
336
+ return mi_page_usable_aligned_size_of(page, p);
337
+ }
338
+ }
339
+
340
+ mi_decl_nodiscard size_t mi_usable_size(const void* p) mi_attr_noexcept {
341
+ return _mi_usable_size(p, "mi_usable_size");
342
+ }
343
+
344
+
345
+ // ------------------------------------------------------
346
+ // Free variants
347
+ // ------------------------------------------------------
348
+
349
+ void mi_free_size(void* p, size_t size) mi_attr_noexcept {
350
+ MI_UNUSED_RELEASE(size);
351
+ #if MI_DEBUG
352
+ const size_t available = _mi_usable_size(p,"mi_free_size");
353
+ mi_assert(p == NULL || size <= available || available == 0 /* invalid pointer */ );
354
+ #endif
355
+ mi_free(p);
356
+ }
357
+
358
+ void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept {
359
+ MI_UNUSED_RELEASE(alignment);
360
+ mi_assert(((uintptr_t)p % alignment) == 0);
361
+ mi_free_size(p,size);
362
+ }
363
+
364
+ void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept {
365
+ MI_UNUSED_RELEASE(alignment);
366
+ mi_assert(((uintptr_t)p % alignment) == 0);
367
+ mi_free(p);
368
+ }
369
+
370
+
371
+ // ------------------------------------------------------
372
+ // Check for double free in secure and debug mode
373
+ // This is somewhat expensive so only enabled for secure mode 4
374
+ // ------------------------------------------------------
375
+
376
+ #if (MI_ENCODE_FREELIST && (MI_SECURE>=4 || MI_DEBUG!=0))
377
+ // linear check if the free list contains a specific element
378
+ static bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, const mi_block_t* elem) {
379
+ while (list != NULL) {
380
+ if (elem==list) return true;
381
+ list = mi_block_next(page, list);
382
+ }
383
+ return false;
384
+ }
385
+
386
+ static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) {
387
+ // The decoded value is in the same page (or NULL).
388
+ // Walk the free lists to verify positively if it is already freed
389
+ if (mi_list_contains(page, page->free, block) ||
390
+ mi_list_contains(page, page->local_free, block) ||
391
+ mi_list_contains(page, mi_page_thread_free(page), block))
392
+ {
393
+ _mi_error_message(EAGAIN, "double free detected of block %p with size %zu\n", block, mi_page_block_size(page));
394
+ return true;
395
+ }
396
+ return false;
397
+ }
398
+
399
+ #define mi_track_page(page,access) { size_t psize; void* pstart = _mi_page_start(_mi_page_segment(page),page,&psize); mi_track_mem_##access( pstart, psize); }
400
+
401
+ static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) {
402
+ bool is_double_free = false;
403
+ mi_block_t* n = mi_block_nextx(page, block, page->keys); // pretend it is freed, and get the decoded first field
404
+ if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 && // quick check: aligned pointer?
405
+ (n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL?
406
+ {
407
+ // Suspicious: decoded value a in block is in the same page (or NULL) -- maybe a double free?
408
+ // (continue in separate function to improve code generation)
409
+ is_double_free = mi_check_is_double_freex(page, block);
410
+ }
411
+ return is_double_free;
412
+ }
413
+ #else
414
+ static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) {
415
+ MI_UNUSED(page);
416
+ MI_UNUSED(block);
417
+ return false;
418
+ }
419
+ #endif
420
+
421
+
422
+ // ---------------------------------------------------------------------------
423
+ // Check for heap block overflow by setting up padding at the end of the block
424
+ // ---------------------------------------------------------------------------
425
+
426
+ #if MI_PADDING // && !MI_TRACK_ENABLED
427
+ static bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* block, size_t* delta, size_t* bsize) {
428
+ *bsize = mi_page_usable_block_size(page);
429
+ const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + *bsize);
430
+ mi_track_mem_defined(padding,sizeof(mi_padding_t));
431
+ *delta = padding->delta;
432
+ uint32_t canary = padding->canary;
433
+ uintptr_t keys[2];
434
+ keys[0] = page->keys[0];
435
+ keys[1] = page->keys[1];
436
+ bool ok = (mi_ptr_encode_canary(page,block,keys) == canary && *delta <= *bsize);
437
+ mi_track_mem_noaccess(padding,sizeof(mi_padding_t));
438
+ return ok;
439
+ }
440
+
441
+ // Return the exact usable size of a block.
442
+ static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) {
443
+ size_t bsize;
444
+ size_t delta;
445
+ bool ok = mi_page_decode_padding(page, block, &delta, &bsize);
446
+ mi_assert_internal(ok); mi_assert_internal(delta <= bsize);
447
+ return (ok ? bsize - delta : 0);
448
+ }
449
+
450
+ // When a non-thread-local block is freed, it becomes part of the thread delayed free
451
+ // list that is freed later by the owning heap. If the exact usable size is too small to
452
+ // contain the pointer for the delayed list, then shrink the padding (by decreasing delta)
453
+ // so it will later not trigger an overflow error in `mi_free_block`.
454
+ void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) {
455
+ size_t bsize;
456
+ size_t delta;
457
+ bool ok = mi_page_decode_padding(page, block, &delta, &bsize);
458
+ mi_assert_internal(ok);
459
+ if (!ok || (bsize - delta) >= min_size) return; // usually already enough space
460
+ mi_assert_internal(bsize >= min_size);
461
+ if (bsize < min_size) return; // should never happen
462
+ size_t new_delta = (bsize - min_size);
463
+ mi_assert_internal(new_delta < bsize);
464
+ mi_padding_t* padding = (mi_padding_t*)((uint8_t*)block + bsize);
465
+ mi_track_mem_defined(padding,sizeof(mi_padding_t));
466
+ padding->delta = (uint32_t)new_delta;
467
+ mi_track_mem_noaccess(padding,sizeof(mi_padding_t));
468
+ }
469
+ #else
470
+ static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) {
471
+ MI_UNUSED(block);
472
+ return mi_page_usable_block_size(page);
473
+ }
474
+
475
+ void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) {
476
+ MI_UNUSED(page);
477
+ MI_UNUSED(block);
478
+ MI_UNUSED(min_size);
479
+ }
480
+ #endif
481
+
482
+ #if MI_PADDING && MI_PADDING_CHECK
483
+
484
+ static bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, size_t* size, size_t* wrong) {
485
+ size_t bsize;
486
+ size_t delta;
487
+ bool ok = mi_page_decode_padding(page, block, &delta, &bsize);
488
+ *size = *wrong = bsize;
489
+ if (!ok) return false;
490
+ mi_assert_internal(bsize >= delta);
491
+ *size = bsize - delta;
492
+ if (!mi_page_is_huge(page)) {
493
+ uint8_t* fill = (uint8_t*)block + bsize - delta;
494
+ const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // check at most the first N padding bytes
495
+ mi_track_mem_defined(fill, maxpad);
496
+ for (size_t i = 0; i < maxpad; i++) {
497
+ if (fill[i] != MI_DEBUG_PADDING) {
498
+ *wrong = bsize - delta + i;
499
+ ok = false;
500
+ break;
501
+ }
502
+ }
503
+ mi_track_mem_noaccess(fill, maxpad);
504
+ }
505
+ return ok;
506
+ }
507
+
508
+ static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {
509
+ size_t size;
510
+ size_t wrong;
511
+ if (!mi_verify_padding(page,block,&size,&wrong)) {
512
+ _mi_error_message(EFAULT, "buffer overflow in heap block %p of size %zu: write after %zu bytes\n", block, size, wrong );
513
+ }
514
+ }
515
+
516
+ #else
517
+
518
+ static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) {
519
+ MI_UNUSED(page);
520
+ MI_UNUSED(block);
521
+ }
522
+
523
+ #endif
524
+
525
+ // only maintain stats for smaller objects if requested
526
+ #if (MI_STAT>0)
527
+ static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {
528
+ MI_UNUSED(block);
529
+ mi_heap_t* const heap = mi_heap_get_default();
530
+ const size_t bsize = mi_page_usable_block_size(page);
531
+ // #if (MI_STAT>1)
532
+ // const size_t usize = mi_page_usable_size_of(page, block);
533
+ // mi_heap_stat_decrease(heap, malloc_requested, usize);
534
+ // #endif
535
+ if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) {
536
+ mi_heap_stat_decrease(heap, malloc_normal, bsize);
537
+ #if (MI_STAT > 1)
538
+ mi_heap_stat_decrease(heap, malloc_bins[_mi_bin(bsize)], 1);
539
+ #endif
540
+ }
541
+ //else if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
542
+ // mi_heap_stat_decrease(heap, malloc_large, bsize);
543
+ //}
544
+ else {
545
+ mi_heap_stat_decrease(heap, malloc_huge, bsize);
546
+ }
547
+ }
548
+ #else
549
+ static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {
550
+ MI_UNUSED(page); MI_UNUSED(block);
551
+ }
552
+ #endif
553
+
554
+
555
+ // Remove guard page when building with MI_GUARDED
556
+ #if MI_GUARDED
557
+ static void mi_block_unguard(mi_page_t* page, mi_block_t* block, void* p) {
558
+ MI_UNUSED(p);
559
+ mi_assert_internal(mi_block_ptr_is_guarded(block, p));
560
+ mi_assert_internal(mi_page_has_aligned(page));
561
+ mi_assert_internal((uint8_t*)p - (uint8_t*)block >= (ptrdiff_t)sizeof(mi_block_t));
562
+ mi_assert_internal(block->next == MI_BLOCK_TAG_GUARDED);
563
+
564
+ const size_t bsize = mi_page_block_size(page);
565
+ const size_t psize = _mi_os_page_size();
566
+ mi_assert_internal(bsize > psize);
567
+ mi_assert_internal(_mi_page_segment(page)->allow_decommit);
568
+ void* gpage = (uint8_t*)block + bsize - psize;
569
+ mi_assert_internal(_mi_is_aligned(gpage, psize));
570
+ _mi_os_unprotect(gpage, psize);
571
+ }
572
+ #endif