@shd101wyy/yo 0.1.23 → 0.1.25

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 (88) hide show
  1. package/.github/skills/yo-async-effects/async-effects-recipes.md +74 -1
  2. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +115 -0
  3. package/.github/skills/yo-syntax/syntax-cheatsheet.md +626 -6
  4. package/out/cjs/index.cjs +563 -564
  5. package/out/cjs/yo-cli.cjs +722 -715
  6. package/out/cjs/yo-lsp.cjs +601 -602
  7. package/out/esm/index.mjs +506 -507
  8. package/out/types/src/codegen/utils/index.d.ts +1 -0
  9. package/out/types/src/expr.d.ts +1 -0
  10. package/out/types/src/parser.d.ts +1 -0
  11. package/out/types/src/test-runner.d.ts +1 -0
  12. package/out/types/tsconfig.tsbuildinfo +1 -1
  13. package/package.json +1 -1
  14. package/std/build.yo +2 -2
  15. package/std/collections/array_list.yo +26 -0
  16. package/std/imm/map.yo +15 -15
  17. package/std/imm/sorted_map.yo +14 -14
  18. package/std/imm/string.yo +4 -4
  19. package/std/prelude.yo +18 -23
  20. package/std/process/command.yo +8 -8
  21. package/std/string/string.yo +76 -55
  22. package/std/string/unicode.yo +6 -6
  23. package/std/sys/signal.yo +6 -6
  24. package/vendor/mimalloc/.github/workflows/release.yaml +55 -0
  25. package/vendor/mimalloc/.github/workflows/stale.yaml +27 -0
  26. package/vendor/mimalloc/.github/workflows/test.yaml +163 -0
  27. package/vendor/mimalloc/CMakeLists.txt +52 -33
  28. package/vendor/mimalloc/azure-pipelines.yml +4 -3
  29. package/vendor/mimalloc/bin/bundle.bat +74 -0
  30. package/vendor/mimalloc/bin/bundle.sh +232 -0
  31. package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +2 -2
  32. package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +1 -1
  33. package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +2 -2
  34. package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +1 -1
  35. package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +1 -1
  36. package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +4 -3
  37. package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +1 -1
  38. package/vendor/mimalloc/doc/mimalloc-doc.h +42 -4
  39. package/vendor/mimalloc/doc/release-notes.md +15 -0
  40. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +3 -3
  41. package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj +511 -0
  42. package/vendor/mimalloc/ide/vs2022/mimalloc-override-static-lib.vcxproj.filters +117 -0
  43. package/vendor/mimalloc/ide/vs2022/mimalloc-test-dep.vcxproj +360 -0
  44. package/vendor/mimalloc/ide/vs2022/mimalloc-test-override-static.vcxproj +310 -0
  45. package/vendor/mimalloc/ide/vs2022/mimalloc.sln +92 -35
  46. package/vendor/mimalloc/include/mimalloc/atomic.h +178 -182
  47. package/vendor/mimalloc/include/mimalloc/bits.h +8 -10
  48. package/vendor/mimalloc/include/mimalloc/internal.h +76 -32
  49. package/vendor/mimalloc/include/mimalloc/prim.h +25 -18
  50. package/vendor/mimalloc/include/mimalloc/track.h +7 -2
  51. package/vendor/mimalloc/include/mimalloc/types.h +57 -29
  52. package/vendor/mimalloc/include/mimalloc-override.h +10 -10
  53. package/vendor/mimalloc/include/mimalloc-stats.h +18 -6
  54. package/vendor/mimalloc/include/mimalloc.h +22 -12
  55. package/vendor/mimalloc/readme.md +42 -17
  56. package/vendor/mimalloc/src/alloc-aligned.c +13 -11
  57. package/vendor/mimalloc/src/alloc-override.c +97 -17
  58. package/vendor/mimalloc/src/alloc-posix.c +44 -27
  59. package/vendor/mimalloc/src/alloc.c +73 -23
  60. package/vendor/mimalloc/src/arena-meta.c +3 -3
  61. package/vendor/mimalloc/src/arena.c +380 -192
  62. package/vendor/mimalloc/src/bitmap.c +68 -18
  63. package/vendor/mimalloc/src/bitmap.h +8 -4
  64. package/vendor/mimalloc/src/free.c +83 -47
  65. package/vendor/mimalloc/src/heap.c +94 -40
  66. package/vendor/mimalloc/src/init.c +273 -102
  67. package/vendor/mimalloc/src/libc.c +53 -8
  68. package/vendor/mimalloc/src/options.c +43 -40
  69. package/vendor/mimalloc/src/os.c +110 -45
  70. package/vendor/mimalloc/src/page-map.c +14 -8
  71. package/vendor/mimalloc/src/page-queue.c +9 -6
  72. package/vendor/mimalloc/src/page.c +26 -16
  73. package/vendor/mimalloc/src/prim/emscripten/prim.c +10 -1
  74. package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +35 -16
  75. package/vendor/mimalloc/src/prim/unix/prim.c +26 -22
  76. package/vendor/mimalloc/src/prim/wasi/prim.c +7 -4
  77. package/vendor/mimalloc/src/prim/windows/prim.c +247 -44
  78. package/vendor/mimalloc/src/random.c +8 -3
  79. package/vendor/mimalloc/src/stats.c +59 -48
  80. package/vendor/mimalloc/src/theap.c +85 -44
  81. package/vendor/mimalloc/src/threadlocal.c +102 -41
  82. package/vendor/mimalloc/test/main-override-static.c +31 -2
  83. package/vendor/mimalloc/test/main-override.c +27 -14
  84. package/vendor/mimalloc/test/main-static-dep.cpp +46 -0
  85. package/vendor/mimalloc/test/main-static-dep.h +11 -0
  86. package/vendor/mimalloc/test/test-api-fill.c +2 -2
  87. package/vendor/mimalloc/test/test-stress.c +3 -3
  88. package/vendor/mimalloc/test/test-wrong.c +11 -7
@@ -11,6 +11,7 @@ terms of the MIT license. A copy of the license can be found in the file
11
11
  #include "mimalloc/internal.h"
12
12
  #include "mimalloc/prim.h"
13
13
  #include <stdio.h> // fputs, stderr
14
+ #include <stdlib.h> // atexit
14
15
 
15
16
  // xbox has no console IO
16
17
  #if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
@@ -86,15 +87,13 @@ typedef BOOL (__stdcall *PGetPhysicallyInstalledSystemMemory)( PULONGLONG TotalM
86
87
  typedef BOOL (__stdcall* PGetVersionExW)(LPOSVERSIONINFOW lpVersionInformation);
87
88
 
88
89
 
90
+
89
91
  //---------------------------------------------
90
92
  // Enable large page support dynamically (if possible)
91
93
  //---------------------------------------------
92
94
 
93
- static bool win_enable_large_os_pages(size_t* large_page_size)
95
+ static bool win_enable_large_os_pages_once(size_t* large_page_size)
94
96
  {
95
- static bool large_initialized = false;
96
- if (large_initialized) return (_mi_os_large_page_size() > 0);
97
- large_initialized = true;
98
97
  if (pGetLargePageMinimum==NULL) return false; // no large page support (xbox etc.)
99
98
 
100
99
  // Try to see if large OS pages are supported
@@ -128,6 +127,13 @@ static bool win_enable_large_os_pages(size_t* large_page_size)
128
127
  return (ok!=0);
129
128
  }
130
129
 
130
+ static bool win_enable_large_os_pages(size_t* large_page_size) {
131
+ mi_atomic_do_once {
132
+ win_enable_large_os_pages_once(large_page_size);
133
+ }
134
+ return (_mi_os_large_page_size() > 0);
135
+ }
136
+
131
137
 
132
138
  //---------------------------------------------
133
139
  // Initialize
@@ -417,8 +423,8 @@ static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int num
417
423
 
418
424
  MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };
419
425
  // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages
420
- static bool mi_huge_pages_available = true;
421
- if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) {
426
+ static _Atomic(size_t) mi_huge_pages_available = MI_ATOMIC_VAR_INIT(1);
427
+ if (pNtAllocateVirtualMemoryEx != NULL && mi_atomic_load_acquire(&mi_huge_pages_available) != 0) {
422
428
  params[0].Type.Type = MiMemExtendedParameterAttributeFlags;
423
429
  params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE;
424
430
  ULONG param_count = 1;
@@ -435,7 +441,7 @@ static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int num
435
441
  }
436
442
  else {
437
443
  // fall back to regular large pages
438
- mi_huge_pages_available = false; // don't try further huge pages
444
+ mi_atomic_store_release(&mi_huge_pages_available,0); // don't try further huge pages
439
445
  _mi_warning_message("unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\n", err);
440
446
  }
441
447
  }
@@ -561,10 +567,11 @@ void _mi_prim_process_info(mi_process_info_t* pinfo)
561
567
  pinfo->stime = filetime_msecs(&st);
562
568
 
563
569
  // load psapi on demand
564
- if (pGetProcessMemoryInfo == NULL) {
570
+ mi_atomic_do_once {
565
571
  HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll"));
566
572
  if (hDll != NULL) {
567
573
  pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo");
574
+ // FreeLibrary(hDll); // don't free
568
575
  }
569
576
  }
570
577
 
@@ -630,7 +637,7 @@ void _mi_prim_out_stderr( const char* msg )
630
637
  // Note: on windows, environment names are not case sensitive.
631
638
  bool _mi_prim_getenv(const char* name, char* result, size_t result_size) {
632
639
  result[0] = 0;
633
- size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size);
640
+ const size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size);
634
641
  return (len > 0 && len < result_size);
635
642
  }
636
643
 
@@ -663,13 +670,16 @@ typedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG);
663
670
  static PBCryptGenRandom pBCryptGenRandom = NULL;
664
671
 
665
672
  bool _mi_prim_random_buf(void* buf, size_t buf_len) {
666
- if (pBCryptGenRandom == NULL) {
673
+ mi_assert(buf_len <= ULONG_MAX);
674
+ if (buf_len > ULONG_MAX) return false;
675
+ mi_atomic_do_once {
667
676
  HINSTANCE hDll = LoadLibrary(TEXT("bcrypt.dll"));
668
677
  if (hDll != NULL) {
669
678
  pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, "BCryptGenRandom");
679
+ // FreeLibrary(hDll); // don't free
670
680
  }
671
- if (pBCryptGenRandom == NULL) return false;
672
681
  }
682
+ if (pBCryptGenRandom == NULL) return false;
673
683
  return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);
674
684
  }
675
685
 
@@ -693,47 +703,22 @@ bool _mi_prim_thread_is_in_threadpool(void) {
693
703
  return false;
694
704
  }
695
705
 
706
+ void _mi_prim_thread_yield(void) {
707
+ SwitchToThread();
708
+ }
696
709
 
697
710
  //----------------------------------------------------------------
698
711
  // Process & Thread Init/Done
699
712
  //----------------------------------------------------------------
700
713
 
701
- #if MI_WIN_USE_FIXED_TLS==1
702
- mi_decl_cache_align size_t _mi_win_tls_offset = 0;
703
- #endif
704
-
705
714
  //static void mi_debug_out(const char* s) {
706
715
  // HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
707
716
  // WriteConsole(h, s, (DWORD)_mi_strlen(s), NULL, NULL);
708
717
  //}
709
718
 
710
- static void mi_win_tls_init(DWORD reason) {
711
- if (reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH) {
712
- #if MI_WIN_USE_FIXED_TLS==1 // we must allocate a TLS slot dynamically
713
- if (_mi_win_tls_offset == 0 && reason == DLL_PROCESS_ATTACH) {
714
- const DWORD tls_slot = TlsAlloc(); // usually returns slot 1
715
- if (tls_slot == TLS_OUT_OF_INDEXES) {
716
- _mi_error_message(EFAULT, "unable to allocate the a TLS slot (rebuild without MI_WIN_USE_FIXED_TLS?)\n");
717
- }
718
- _mi_win_tls_offset = (size_t)tls_slot * sizeof(void*);
719
- }
720
- #endif
721
- #if MI_HAS_TLS_SLOT >= 2 // we must initialize the TLS slot before any allocation
722
- if (_mi_theap_default() == NULL) {
723
- _mi_theap_default_set((mi_theap_t*)&_mi_theap_empty);
724
- #if MI_DEBUG && MI_WIN_USE_FIXED_TLS==1
725
- void* const p = TlsGetValue((DWORD)(_mi_win_tls_offset / sizeof(void*)));
726
- mi_assert_internal(p == (void*)&_mi_theap_empty);
727
- #endif
728
- }
729
- #endif
730
- }
731
- }
732
-
733
719
  static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
734
720
  MI_UNUSED(reserved);
735
721
  MI_UNUSED(module);
736
- mi_win_tls_init(reason);
737
722
  if (reason==DLL_PROCESS_ATTACH) {
738
723
  _mi_auto_process_init();
739
724
  }
@@ -746,7 +731,223 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
746
731
  }
747
732
 
748
733
 
749
- #if defined(MI_SHARED_LIB)
734
+ /* -----------------------------------------------------------------------
735
+ Auto initialize and finalize mimalloc on process and thread start/end.
736
+ By default we use a combination of CRT init and TLS sections for
737
+ both static and dynamic linkage (`MI_WIN_INIT_USE_CRT_TLS`).
738
+ ------------------------------------------------------------------------- */
739
+ #if !defined(MI_WIN_INIT_USE_CRT_TLS) && !defined(MI_WIN_INIT_USE_RAW_DLLMAIN) && !defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && !defined(MI_WIN_INIT_USE_FLS)
740
+ #if !defined(__INTEL_LLVM_COMPILER) && !defined(__INTEL_COMPILER)
741
+ #define MI_WIN_INIT_USE_CRT_TLS 1
742
+ #else
743
+ #define MI_WIN_INIT_USE_TLS_DLLMAIN 1 /* default for Intel ICX, see issue #1268 */
744
+ #endif
745
+ #endif
746
+
747
+ #if defined(MI_WIN_INIT_USE_CRT_TLS)
748
+ #define MI_PRIM_HAS_PROCESS_ATTACH 1
749
+ // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.
750
+ void _mi_prim_thread_init_auto_done(void) {}
751
+ void _mi_prim_thread_done_auto_done(void) {}
752
+ void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {
753
+ MI_UNUSED(theap);
754
+ }
755
+
756
+ static bool mi_module_is_dll(PVOID mod) {
757
+ if (mod==NULL) return false;
758
+ PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;
759
+ PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);
760
+ return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);
761
+ }
762
+
763
+ static bool mi_current_module_is_dll(void) {
764
+ HMODULE mod = NULL;
765
+ const BOOL ok = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)mi_current_module_is_dll, &mod);
766
+ return (ok && mi_module_is_dll(mod));
767
+ }
768
+
769
+ // Hook into CRT initialization and finalization.
770
+ static void mi_cdecl mi_crt_done(void) {
771
+ // mi_debug_out(mi_current_module_is_dll() ? "crt dll done\n" : "crt exe done\n");
772
+ mi_win_main(NULL, DLL_PROCESS_DETACH, 0);
773
+ }
774
+
775
+ static int mi_cdecl mi_crt_init(void) {
776
+ // mi_debug_out(mi_current_module_is_dll() ? "crt dll init\n" : "crt exe init\n");
777
+ if (mi_current_module_is_dll()) {
778
+ // in a dll, atexit (crt_done) is called after tls process detach
779
+ atexit(&mi_crt_done);
780
+ }
781
+ return 0;
782
+ }
783
+
784
+ // We also hook into the Windows loader TLS initialization and finalization.
785
+ static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {
786
+ if (reason == DLL_THREAD_ATTACH) {
787
+ //mi_debug_out("tls thread attach\n");
788
+ mi_win_main(module, reason, reserved);
789
+ }
790
+ else if (reason == DLL_PROCESS_ATTACH) {
791
+ // mi_debug_out(mi_module_is_dll(module) ? "tls dll process attach\n" : "tls exe process attach\n");
792
+ // tls process attach is always called before crt init
793
+ mi_win_main(module, reason, reserved);
794
+ }
795
+ }
796
+
797
+ static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {
798
+ if (reason == DLL_THREAD_DETACH) {
799
+ //mi_debug_out("tls thread detach\n");
800
+ mi_win_main(module, reason, reserved);
801
+ }
802
+ else if (reason == DLL_PROCESS_DETACH) {
803
+ // mi_debug_out(mi_module_is_dll(module) ? "tls dll process detach\n" : "tls exe process detach\n");
804
+ if (!mi_module_is_dll(module)) {
805
+ // in an exe, tls process detach is called after atexit (mi_crt_done)
806
+ mi_win_main(module, reason, reserved);
807
+ }
808
+ }
809
+ }
810
+
811
+ // Set up TLS callbacks in a statically linked library by using special data sections.
812
+ // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>
813
+ // We use 2 entries to ensure we call attach events before constructors
814
+ // are called, and detach events after destructors are called.
815
+ // We also set up a CRT initialization callback.
816
+ #if defined(__cplusplus)
817
+ extern "C" {
818
+ #endif
819
+
820
+ typedef int (mi_cdecl* mi_crt_callback_t)(void);
821
+ #if defined(_WIN64)
822
+ #pragma comment(linker, "/INCLUDE:_tls_used")
823
+ #pragma comment(linker, "/INCLUDE:_mi_tls_callback_pre")
824
+ #pragma comment(linker, "/INCLUDE:_mi_tls_callback_post")
825
+ #pragma const_seg(".CRT$XLB")
826
+ extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];
827
+ const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
828
+ #pragma const_seg()
829
+ #pragma const_seg(".CRT$XLY")
830
+ extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];
831
+ const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
832
+ #pragma const_seg()
833
+ #pragma const_seg(".CRT$XIB")
834
+ extern const mi_crt_callback_t _mi_crt_callback_init[];
835
+ const mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };
836
+ #pragma const_seg()
837
+ #else
838
+ #pragma comment(linker, "/INCLUDE:__tls_used")
839
+ #pragma comment(linker, "/INCLUDE:__mi_tls_callback_pre")
840
+ #pragma comment(linker, "/INCLUDE:__mi_tls_callback_post")
841
+ #pragma data_seg(".CRT$XLB")
842
+ PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
843
+ #pragma data_seg()
844
+ #pragma data_seg(".CRT$XLY")
845
+ PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
846
+ #pragma data_seg()
847
+ #pragma data_seg(".CRT$XIB")
848
+ mi_crt_callback_t _mi_crt_callback_init[] = { &mi_crt_init };
849
+ #pragma data_seg()
850
+ #endif
851
+
852
+ #if defined(__cplusplus)
853
+ }
854
+ #endif
855
+
856
+ /* ----------------------------------------------------------------
857
+ Here we use a combination of the raw DLL main and TLS sections for
858
+ both static and dynamic linkage. This is perhaps the most robust as
859
+ the raw DLL main ensure we can close mimalloc latest possible.
860
+ However, it can lead to link errors with on `_pRawDllMain` if other
861
+ libraries also try to hook into this (like Boost).
862
+ */
863
+ #elif defined(MI_WIN_INIT_USE_RAW_DLLMAIN)
864
+ #define MI_PRIM_HAS_PROCESS_ATTACH 1
865
+ // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.
866
+ void _mi_prim_thread_init_auto_done(void) {}
867
+ void _mi_prim_thread_done_auto_done(void) {}
868
+ void _mi_prim_thread_associate_default_theap(mi_theap_t* theap) {
869
+ MI_UNUSED(theap);
870
+ }
871
+
872
+ // If linked into a DLL module, this raw entry is called before the CRT attach and
873
+ // after the CRT detach through the CRT _pRawDllMain pointer.
874
+ static BOOL NTAPI mi_dll_main_raw(PVOID module, DWORD reason, LPVOID reserved) {
875
+ mi_win_main(module, reason, reserved);
876
+ return TRUE;
877
+ }
878
+
879
+ // Set the value of the CRT _pRawDllMain pointer
880
+ #if defined(__cplusplus)
881
+ extern "C"
882
+ #endif
883
+ PVOID _pRawDllMain = (PVOID)&mi_dll_main_raw;
884
+
885
+ // We also hook into the Windows loader TLS initialization and finalization.
886
+ // If we are linked into an EXE module we rely on these as `mi_dll_main_raw`
887
+ // is not called (and otherwise we ignore the TLS callbacks by checking if we are in a DLL).
888
+ static bool mi_module_is_dll(PVOID mod) {
889
+ if (mod==NULL) return false;
890
+ PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)mod;
891
+ PIMAGE_NT_HEADERS imageNtHeaders = (PIMAGE_NT_HEADERS)((unsigned char*)imageDosHeader + imageDosHeader->e_lfanew);
892
+ return ((imageNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL);
893
+ }
894
+
895
+ static void NTAPI mi_tls_attach(PVOID module, DWORD reason, LPVOID reserved) {
896
+ if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {
897
+ if (!mi_module_is_dll(module)) {
898
+ mi_win_main(module, reason, reserved);
899
+ }
900
+ }
901
+ }
902
+
903
+ static void NTAPI mi_tls_detach(PVOID module, DWORD reason, LPVOID reserved) {
904
+ if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {
905
+ if (!mi_module_is_dll(module)) {
906
+ mi_win_main(module, reason, reserved);
907
+ }
908
+ }
909
+ }
910
+
911
+ // Set up TLS callbacks in a statically linked library by using special data sections.
912
+ // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>
913
+ // We use 2 entries to ensure we call attach events before constructors
914
+ // are called, and detach events after destructors are called.
915
+ #if defined(__cplusplus)
916
+ extern "C" {
917
+ #endif
918
+
919
+ #if defined(_WIN64)
920
+ #pragma comment(linker, "/INCLUDE:_tls_used")
921
+ #pragma comment(linker, "/INCLUDE:_mi_tls_callback_pre")
922
+ #pragma comment(linker, "/INCLUDE:_mi_tls_callback_post")
923
+ #pragma const_seg(".CRT$XLB")
924
+ extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];
925
+ const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
926
+ #pragma const_seg()
927
+ #pragma const_seg(".CRT$XLY")
928
+ extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];
929
+ const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
930
+ #pragma const_seg()
931
+ #else
932
+ #pragma comment(linker, "/INCLUDE:__tls_used")
933
+ #pragma comment(linker, "/INCLUDE:__mi_tls_callback_pre")
934
+ #pragma comment(linker, "/INCLUDE:__mi_tls_callback_post")
935
+ #pragma data_seg(".CRT$XLB")
936
+ PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_tls_attach };
937
+ #pragma data_seg()
938
+ #pragma data_seg(".CRT$XLY")
939
+ PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_tls_detach };
940
+ #pragma data_seg()
941
+ #endif
942
+
943
+ #if defined(__cplusplus)
944
+ }
945
+ #endif
946
+
947
+ /* --------------------------------------------------------------------
948
+ Legacy options: DllMain, TLS, and FLS
949
+ --------------------------------------------------------------------*/
950
+ #elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN) && defined(MI_SHARED_LIB)
750
951
  #define MI_PRIM_HAS_PROCESS_ATTACH 1
751
952
 
752
953
  // Windows DLL: easy to hook into process_init and thread_done
@@ -762,7 +963,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
762
963
  MI_UNUSED(theap);
763
964
  }
764
965
 
765
- #elif !defined(MI_WIN_USE_FLS)
966
+ #elif defined(MI_WIN_INIT_USE_TLS_DLLMAIN)
766
967
  #define MI_PRIM_HAS_PROCESS_ATTACH 1
767
968
 
768
969
  static void NTAPI mi_win_main_attach(PVOID module, DWORD reason, LPVOID reserved) {
@@ -803,7 +1004,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
803
1004
  #pragma data_seg(".CRT$XLB")
804
1005
  PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };
805
1006
  #pragma data_seg()
806
- #pragma data_seg(".CRT$XLY")
1007
+ #pragma data_seg(".CRT$XIY")
807
1008
  PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };
808
1009
  #pragma data_seg()
809
1010
  #endif
@@ -819,7 +1020,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
819
1020
  MI_UNUSED(theap);
820
1021
  }
821
1022
 
822
- #else // deprecated: statically linked, use fiber api
1023
+ #elif defined(MI_WIN_INIT_USE_FLS) // deprecated: statically linked, use fiber api
823
1024
 
824
1025
  #if defined(_MSC_VER) // on clang/gcc use the constructor attribute (in `src/prim/prim.c`)
825
1026
  // MSVC: use data section magic for static libraries
@@ -876,6 +1077,8 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
876
1077
  mi_assert_internal(mi_fls_key != (DWORD)(-1));
877
1078
  FlsSetValue(mi_fls_key, theap);
878
1079
  }
1080
+ #else
1081
+ #error "define windows process and thread auto initialization"
879
1082
  #endif
880
1083
 
881
1084
  // ----------------------------------------------------
@@ -895,7 +1098,6 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
895
1098
  #endif
896
1099
  mi_decl_export void _mi_redirect_entry(DWORD reason) {
897
1100
  // called on redirection; careful as this may be called before DllMain
898
- mi_win_tls_init(reason);
899
1101
  if (reason == DLL_PROCESS_ATTACH) {
900
1102
  mi_redirected = true;
901
1103
  }
@@ -903,6 +1105,7 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
903
1105
  mi_redirected = false;
904
1106
  }
905
1107
  else if (reason == DLL_THREAD_DETACH) {
1108
+ // mi_debug_out("redirect thread detach\n");
906
1109
  _mi_thread_done(NULL);
907
1110
  }
908
1111
  }
@@ -94,7 +94,8 @@ static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t no
94
94
  // since we only use chacha for randomness (and not encryption) we
95
95
  // do not _need_ to read 32-bit values as little endian but we do anyways
96
96
  // just for being compatible :-)
97
- _mi_memzero(ctx, sizeof(*ctx));
97
+ ctx->output_available = 0;
98
+ _mi_memzero(ctx->output,sizeof(ctx->output));
98
99
  for (size_t i = 0; i < 4; i++) {
99
100
  const uint8_t* sigma = (uint8_t*)"expand 32-byte k";
100
101
  ctx->input[i] = read32(sigma,i);
@@ -110,6 +111,7 @@ static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t no
110
111
 
111
112
  static void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) {
112
113
  _mi_memzero(ctx_new, sizeof(*ctx_new));
114
+ ctx_new->weak = ctx->weak;
113
115
  _mi_memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input));
114
116
  ctx_new->input[12] = 0;
115
117
  ctx_new->input[13] = 0;
@@ -178,9 +180,12 @@ static void mi_random_init_ex(mi_random_ctx_t* ctx, bool use_weak) {
178
180
  if (!use_weak) { _mi_warning_message("unable to use secure randomness\n"); }
179
181
  #endif
180
182
  uintptr_t x = _mi_os_random_weak(0);
181
- for (size_t i = 0; i < 8; i++, x++) { // key is eight 32-bit words.
183
+ for (size_t i = 0; i < 32; i+=4, x++) {
182
184
  x = _mi_random_shuffle(x);
183
- ((uint32_t*)key)[i] = (uint32_t)x;
185
+ key[i] = (uint8_t)(x);
186
+ key[i+1] = (uint8_t)(x>>8);
187
+ key[i+2] = (uint8_t)(x>>16);
188
+ key[i+3] = (uint8_t)(x>>24);
184
189
  }
185
190
  ctx->weak = true;
186
191
  }