default_allocators_nil.odin 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package runtime
  2. nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
  3. size, alignment: int,
  4. old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
  5. switch mode {
  6. case .Alloc, .Alloc_Non_Zeroed:
  7. return nil, .Out_Of_Memory
  8. case .Free:
  9. return nil, .None
  10. case .Free_All:
  11. return nil, .Mode_Not_Implemented
  12. case .Resize, .Resize_Non_Zeroed:
  13. if size == 0 {
  14. return nil, .None
  15. }
  16. return nil, .Out_Of_Memory
  17. case .Query_Features:
  18. return nil, .Mode_Not_Implemented
  19. case .Query_Info:
  20. return nil, .Mode_Not_Implemented
  21. }
  22. return nil, .None
  23. }
  24. // nil_allocator returns an allocator which will return `nil` for any result.
  25. // * `.Alloc`, `.Alloc_Non_Zero`, `.Resize`, `.Resize_Non_Zeroed` will return `nil, .Out_Of_Memory`
  26. // * `.Free` will return `nil, .None`
  27. // * `.Free_All` will return `nil, .Mode_Not_Implemented`
  28. // * `.Query_Features`, `.Query_Info` will return `nil, .Mode_Not_Implemented`
  29. //
  30. // This is extremely useful for creating a dynamic array from a buffer which does not nothing
  31. // on a resize/reserve beyond the originally allocated memory.
  32. @(require_results)
  33. nil_allocator :: proc "contextless" () -> Allocator {
  34. return Allocator{
  35. procedure = nil_allocator_proc,
  36. data = nil,
  37. }
  38. }
  39. panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
  40. size, alignment: int,
  41. old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
  42. switch mode {
  43. case .Alloc:
  44. if size > 0 {
  45. panic("panic allocator, .Alloc called", loc=loc)
  46. }
  47. case .Alloc_Non_Zeroed:
  48. if size > 0 {
  49. panic("panic allocator, .Alloc_Non_Zeroed called", loc=loc)
  50. }
  51. case .Resize:
  52. if size > 0 {
  53. panic("panic allocator, .Resize called", loc=loc)
  54. }
  55. case .Resize_Non_Zeroed:
  56. if size > 0 {
  57. panic("panic allocator, .Alloc_Non_Zeroed called", loc=loc)
  58. }
  59. case .Free:
  60. if old_memory != nil {
  61. panic("panic allocator, .Free called", loc=loc)
  62. }
  63. case .Free_All:
  64. panic("panic allocator, .Free_All called", loc=loc)
  65. case .Query_Features:
  66. set := (^Allocator_Mode_Set)(old_memory)
  67. if set != nil {
  68. set^ = {.Query_Features}
  69. }
  70. return nil, nil
  71. case .Query_Info:
  72. panic("panic allocator, .Query_Info called", loc=loc)
  73. }
  74. return nil, nil
  75. }
  76. // panic_allocator returns an allocator which will panic for any non-zero-sized allocation or `query_info`
  77. //
  78. // This is extremely useful for to check when something does a memory operation when it should not, and thus panic.
  79. @(require_results)
  80. panic_allocator :: proc() -> Allocator {
  81. return Allocator{
  82. procedure = panic_allocator_proc,
  83. data = nil,
  84. }
  85. }