error_checks.odin 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. package runtime
  2. bounds_trap :: proc "contextless" () -> ! {
  3. when ODIN_OS == .Windows {
  4. windows_trap_array_bounds()
  5. } else {
  6. trap()
  7. }
  8. }
  9. type_assertion_trap :: proc "contextless" () -> ! {
  10. when ODIN_OS == .Windows {
  11. windows_trap_type_assertion()
  12. } else {
  13. trap()
  14. }
  15. }
  16. bounds_check_error :: proc "contextless" (file: string, line, column: i32, index, count: int) {
  17. if 0 <= index && index < count {
  18. return
  19. }
  20. handle_error :: proc "contextless" (file: string, line, column: i32, index, count: int) {
  21. print_caller_location(Source_Code_Location{file, line, column, ""})
  22. print_string(" Index ")
  23. print_i64(i64(index))
  24. print_string(" is out of range 0..<")
  25. print_i64(i64(count))
  26. print_byte('\n')
  27. bounds_trap()
  28. }
  29. handle_error(file, line, column, index, count)
  30. }
  31. slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int, len: int) -> ! {
  32. print_caller_location(Source_Code_Location{file, line, column, ""})
  33. print_string(" Invalid slice indices ")
  34. print_i64(i64(lo))
  35. print_string(":")
  36. print_i64(i64(hi))
  37. print_string(" is out of range 0..<")
  38. print_i64(i64(len))
  39. print_byte('\n')
  40. bounds_trap()
  41. }
  42. multi_pointer_slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) -> ! {
  43. print_caller_location(Source_Code_Location{file, line, column, ""})
  44. print_string(" Invalid slice indices ")
  45. print_i64(i64(lo))
  46. print_string(":")
  47. print_i64(i64(hi))
  48. print_byte('\n')
  49. bounds_trap()
  50. }
  51. multi_pointer_slice_expr_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) {
  52. if lo <= hi {
  53. return
  54. }
  55. multi_pointer_slice_handle_error(file, line, column, lo, hi)
  56. }
  57. slice_expr_error_hi :: proc "contextless" (file: string, line, column: i32, hi: int, len: int) {
  58. if 0 <= hi && hi <= len {
  59. return
  60. }
  61. slice_handle_error(file, line, column, 0, hi, len)
  62. }
  63. slice_expr_error_lo_hi :: proc "contextless" (file: string, line, column: i32, lo, hi: int, len: int) {
  64. if 0 <= lo && lo <= len && lo <= hi && hi <= len {
  65. return
  66. }
  67. slice_handle_error(file, line, column, lo, hi, len)
  68. }
  69. dynamic_array_expr_error :: proc "contextless" (file: string, line, column: i32, low, high, max: int) {
  70. if 0 <= low && low <= high && high <= max {
  71. return
  72. }
  73. handle_error :: proc "contextless" (file: string, line, column: i32, low, high, max: int) {
  74. print_caller_location(Source_Code_Location{file, line, column, ""})
  75. print_string(" Invalid dynamic array indices ")
  76. print_i64(i64(low))
  77. print_string(":")
  78. print_i64(i64(high))
  79. print_string(" is out of range 0..<")
  80. print_i64(i64(max))
  81. print_byte('\n')
  82. bounds_trap()
  83. }
  84. handle_error(file, line, column, low, high, max)
  85. }
  86. matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) {
  87. if 0 <= row_index && row_index < row_count &&
  88. 0 <= column_index && column_index < column_count {
  89. return
  90. }
  91. handle_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) {
  92. print_caller_location(Source_Code_Location{file, line, column, ""})
  93. print_string(" Matrix indices [")
  94. print_i64(i64(row_index))
  95. print_string(", ")
  96. print_i64(i64(column_index))
  97. print_string(" is out of range [0..<")
  98. print_i64(i64(row_count))
  99. print_string(", 0..<")
  100. print_i64(i64(column_count))
  101. print_string("]")
  102. print_byte('\n')
  103. bounds_trap()
  104. }
  105. handle_error(file, line, column, row_index, column_index, row_count, column_count)
  106. }
  107. type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid) {
  108. if ok {
  109. return
  110. }
  111. handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid) {
  112. print_caller_location(Source_Code_Location{file, line, column, ""})
  113. print_string(" Invalid type assertion from ")
  114. print_typeid(from)
  115. print_string(" to ")
  116. print_typeid(to)
  117. print_byte('\n')
  118. type_assertion_trap()
  119. }
  120. handle_error(file, line, column, from, to)
  121. }
  122. type_assertion_check2 :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid, from_data: rawptr) {
  123. if ok {
  124. return
  125. }
  126. variant_type :: proc "contextless" (id: typeid, data: rawptr) -> typeid {
  127. if id == nil || data == nil {
  128. return id
  129. }
  130. ti := type_info_base(type_info_of(id))
  131. #partial switch v in ti.variant {
  132. case Type_Info_Any:
  133. return (^any)(data).id
  134. case Type_Info_Union:
  135. tag_ptr := uintptr(data) + v.tag_offset
  136. idx := 0
  137. switch v.tag_type.size {
  138. case 1: idx = int((^u8)(tag_ptr)^) - 1
  139. case 2: idx = int((^u16)(tag_ptr)^) - 1
  140. case 4: idx = int((^u32)(tag_ptr)^) - 1
  141. case 8: idx = int((^u64)(tag_ptr)^) - 1
  142. case 16: idx = int((^u128)(tag_ptr)^) - 1
  143. }
  144. if idx < 0 {
  145. return nil
  146. } else if idx < len(v.variants) {
  147. return v.variants[idx].id
  148. }
  149. }
  150. return id
  151. }
  152. handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid, from_data: rawptr) {
  153. actual := variant_type(from, from_data)
  154. print_caller_location(Source_Code_Location{file, line, column, ""})
  155. print_string(" Invalid type assertion from ")
  156. print_typeid(from)
  157. print_string(" to ")
  158. print_typeid(to)
  159. if actual != from {
  160. print_string(", actual type: ")
  161. print_typeid(actual)
  162. }
  163. print_byte('\n')
  164. type_assertion_trap()
  165. }
  166. handle_error(file, line, column, from, to, from_data)
  167. }
  168. make_slice_error_loc :: #force_inline proc "contextless" (loc := #caller_location, len: int) {
  169. if 0 <= len {
  170. return
  171. }
  172. handle_error :: proc "contextless" (loc: Source_Code_Location, len: int) {
  173. print_caller_location(loc)
  174. print_string(" Invalid slice length for make: ")
  175. print_i64(i64(len))
  176. print_byte('\n')
  177. bounds_trap()
  178. }
  179. handle_error(loc, len)
  180. }
  181. make_dynamic_array_error_loc :: #force_inline proc "contextless" (using loc := #caller_location, len, cap: int) {
  182. if 0 <= len && len <= cap {
  183. return
  184. }
  185. handle_error :: proc "contextless" (loc: Source_Code_Location, len, cap: int) {
  186. print_caller_location(loc)
  187. print_string(" Invalid dynamic array parameters for make: ")
  188. print_i64(i64(len))
  189. print_byte(':')
  190. print_i64(i64(cap))
  191. print_byte('\n')
  192. bounds_trap()
  193. }
  194. handle_error(loc, len, cap)
  195. }
  196. make_map_expr_error_loc :: #force_inline proc "contextless" (loc := #caller_location, cap: int) {
  197. if 0 <= cap {
  198. return
  199. }
  200. handle_error :: proc "contextless" (loc: Source_Code_Location, cap: int) {
  201. print_caller_location(loc)
  202. print_string(" Invalid map capacity for make: ")
  203. print_i64(i64(cap))
  204. print_byte('\n')
  205. bounds_trap()
  206. }
  207. handle_error(loc, cap)
  208. }
  209. bounds_check_error_loc :: #force_inline proc "contextless" (using loc := #caller_location, index, count: int) {
  210. bounds_check_error(file_path, line, column, index, count)
  211. }
  212. slice_expr_error_hi_loc :: #force_inline proc "contextless" (using loc := #caller_location, hi: int, len: int) {
  213. slice_expr_error_hi(file_path, line, column, hi, len)
  214. }
  215. slice_expr_error_lo_hi_loc :: #force_inline proc "contextless" (using loc := #caller_location, lo, hi: int, len: int) {
  216. slice_expr_error_lo_hi(file_path, line, column, lo, hi, len)
  217. }
  218. dynamic_array_expr_error_loc :: #force_inline proc "contextless" (using loc := #caller_location, low, high, max: int) {
  219. dynamic_array_expr_error(file_path, line, column, low, high, max)
  220. }