core.odin 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. // This is the runtime code required by the compiler
  2. // IMPORTANT NOTE(bill): Do not change the order of any of this data
  3. // The compiler relies upon this _exact_ order
  4. //
  5. // Naming Conventions:
  6. // In general, Ada_Case for types and snake_case for values
  7. //
  8. // Package Name: snake_case (but prefer single word)
  9. // Import Name: snake_case (but prefer single word)
  10. // Types: Ada_Case
  11. // Enum Values: Ada_Case
  12. // Procedures: snake_case
  13. // Local Variables: snake_case
  14. // Constant Variables: SCREAMING_SNAKE_CASE
  15. //
  16. // IMPORTANT NOTE(bill): `type_info_of` cannot be used within a
  17. // #shared_global_scope due to the internals of the compiler.
  18. // This could change at a later date if the all these data structures are
  19. // implemented within the compiler rather than in this "preload" file
  20. //
  21. #+no-instrumentation
  22. package runtime
  23. import "base:intrinsics"
  24. // NOTE(bill): This must match the compiler's
  25. Calling_Convention :: enum u8 {
  26. Invalid = 0,
  27. Odin = 1,
  28. Contextless = 2,
  29. CDecl = 3,
  30. Std_Call = 4,
  31. Fast_Call = 5,
  32. None = 6,
  33. Naked = 7,
  34. _ = 8, // reserved
  35. Win64 = 9,
  36. SysV = 10,
  37. }
  38. Type_Info_Enum_Value :: distinct i64
  39. Platform_Endianness :: enum u8 {
  40. Platform = 0,
  41. Little = 1,
  42. Big = 2,
  43. }
  44. // Procedure type to test whether two values of the same type are equal
  45. Equal_Proc :: distinct proc "contextless" (rawptr, rawptr) -> bool
  46. // Procedure type to hash a value, default seed value is 0
  47. Hasher_Proc :: distinct proc "contextless" (data: rawptr, seed: uintptr = 0) -> uintptr
  48. Type_Info_Struct_Soa_Kind :: enum u8 {
  49. None = 0,
  50. Fixed = 1,
  51. Slice = 2,
  52. Dynamic = 3,
  53. }
  54. Type_Info_String_Encoding_Kind :: enum u8 {
  55. UTF_8 = 0,
  56. UTF_16 = 1,
  57. }
  58. // Variant Types
  59. Type_Info_Named :: struct {
  60. name: string,
  61. base: ^Type_Info,
  62. pkg: string,
  63. loc: ^Source_Code_Location,
  64. }
  65. Type_Info_Integer :: struct {signed: bool, endianness: Platform_Endianness}
  66. Type_Info_Rune :: struct {}
  67. Type_Info_Float :: struct {endianness: Platform_Endianness}
  68. Type_Info_Complex :: struct {}
  69. Type_Info_Quaternion :: struct {}
  70. Type_Info_String :: struct {is_cstring: bool, encoding: Type_Info_String_Encoding_Kind}
  71. Type_Info_Boolean :: struct {}
  72. Type_Info_Any :: struct {}
  73. Type_Info_Type_Id :: struct {}
  74. Type_Info_Pointer :: struct {
  75. elem: ^Type_Info, // nil -> rawptr
  76. }
  77. Type_Info_Multi_Pointer :: struct {
  78. elem: ^Type_Info,
  79. }
  80. Type_Info_Procedure :: struct {
  81. params: ^Type_Info, // Type_Info_Parameters
  82. results: ^Type_Info, // Type_Info_Parameters
  83. variadic: bool,
  84. convention: Calling_Convention,
  85. }
  86. Type_Info_Array :: struct {
  87. elem: ^Type_Info,
  88. elem_size: int,
  89. count: int,
  90. }
  91. Type_Info_Enumerated_Array :: struct {
  92. elem: ^Type_Info,
  93. index: ^Type_Info,
  94. elem_size: int,
  95. count: int,
  96. min_value: Type_Info_Enum_Value,
  97. max_value: Type_Info_Enum_Value,
  98. is_sparse: bool,
  99. }
  100. Type_Info_Dynamic_Array :: struct {elem: ^Type_Info, elem_size: int}
  101. Type_Info_Slice :: struct {elem: ^Type_Info, elem_size: int}
  102. Type_Info_Parameters :: struct { // Only used for procedures parameters and results
  103. types: []^Type_Info,
  104. names: []string,
  105. }
  106. Type_Info_Struct_Flags :: distinct bit_set[Type_Info_Struct_Flag; u8]
  107. Type_Info_Struct_Flag :: enum u8 {
  108. packed = 0,
  109. raw_union = 1,
  110. _ = 2,
  111. align = 3,
  112. }
  113. Type_Info_Struct :: struct {
  114. // Slice these with `field_count`
  115. types: [^]^Type_Info `fmt:"v,field_count"`,
  116. names: [^]string `fmt:"v,field_count"`,
  117. offsets: [^]uintptr `fmt:"v,field_count"`,
  118. usings: [^]bool `fmt:"v,field_count"`,
  119. tags: [^]string `fmt:"v,field_count"`,
  120. field_count: i32,
  121. flags: Type_Info_Struct_Flags,
  122. // These are only set iff this structure is an SOA structure
  123. soa_kind: Type_Info_Struct_Soa_Kind,
  124. soa_len: i32,
  125. soa_base_type: ^Type_Info,
  126. equal: Equal_Proc, // set only when the struct has .Comparable set but does not have .Simple_Compare set
  127. }
  128. Type_Info_Union :: struct {
  129. variants: []^Type_Info,
  130. tag_offset: uintptr,
  131. tag_type: ^Type_Info,
  132. equal: Equal_Proc, // set only when the struct has .Comparable set but does not have .Simple_Compare set
  133. custom_align: bool,
  134. no_nil: bool,
  135. shared_nil: bool,
  136. }
  137. Type_Info_Enum :: struct {
  138. base: ^Type_Info,
  139. names: []string,
  140. values: []Type_Info_Enum_Value,
  141. }
  142. Type_Info_Map :: struct {
  143. key: ^Type_Info,
  144. value: ^Type_Info,
  145. map_info: ^Map_Info,
  146. }
  147. Type_Info_Bit_Set :: struct {
  148. elem: ^Type_Info,
  149. underlying: ^Type_Info, // Possibly nil
  150. lower: i64,
  151. upper: i64,
  152. }
  153. Type_Info_Simd_Vector :: struct {
  154. elem: ^Type_Info,
  155. elem_size: int,
  156. count: int,
  157. }
  158. Type_Info_Matrix :: struct {
  159. elem: ^Type_Info,
  160. elem_size: int,
  161. elem_stride: int, // elem_stride >= row_count
  162. row_count: int,
  163. column_count: int,
  164. // Total element count = column_count * elem_stride
  165. layout: enum u8 {
  166. Column_Major, // array of column vectors
  167. Row_Major, // array of row vectors
  168. },
  169. }
  170. Type_Info_Soa_Pointer :: struct {
  171. elem: ^Type_Info,
  172. }
  173. Type_Info_Bit_Field :: struct {
  174. backing_type: ^Type_Info,
  175. names: [^]string `fmt:"v,field_count"`,
  176. types: [^]^Type_Info `fmt:"v,field_count"`,
  177. bit_sizes: [^]uintptr `fmt:"v,field_count"`,
  178. bit_offsets: [^]uintptr `fmt:"v,field_count"`,
  179. tags: [^]string `fmt:"v,field_count"`,
  180. field_count: int,
  181. }
  182. Type_Info_Flag :: enum u8 {
  183. Comparable = 0,
  184. Simple_Compare = 1,
  185. }
  186. Type_Info_Flags :: distinct bit_set[Type_Info_Flag; u32]
  187. Type_Info :: struct {
  188. size: int,
  189. align: int,
  190. flags: Type_Info_Flags,
  191. id: typeid,
  192. variant: union {
  193. Type_Info_Named,
  194. Type_Info_Integer,
  195. Type_Info_Rune,
  196. Type_Info_Float,
  197. Type_Info_Complex,
  198. Type_Info_Quaternion,
  199. Type_Info_String,
  200. Type_Info_Boolean,
  201. Type_Info_Any,
  202. Type_Info_Type_Id,
  203. Type_Info_Pointer,
  204. Type_Info_Multi_Pointer,
  205. Type_Info_Procedure,
  206. Type_Info_Array,
  207. Type_Info_Enumerated_Array,
  208. Type_Info_Dynamic_Array,
  209. Type_Info_Slice,
  210. Type_Info_Parameters,
  211. Type_Info_Struct,
  212. Type_Info_Union,
  213. Type_Info_Enum,
  214. Type_Info_Map,
  215. Type_Info_Bit_Set,
  216. Type_Info_Simd_Vector,
  217. Type_Info_Matrix,
  218. Type_Info_Soa_Pointer,
  219. Type_Info_Bit_Field,
  220. },
  221. }
  222. // NOTE(bill): only the ones that are needed (not all types)
  223. // This will be set by the compiler
  224. type_table: []^Type_Info
  225. args__: []cstring
  226. when ODIN_OS == .Windows {
  227. // NOTE(Jeroen): If we're a Windows DLL, fwdReason will be populated.
  228. // This tells a DLL if it's first loaded, about to be unloaded, or a thread is joining/exiting.
  229. DLL_Forward_Reason :: enum u32 {
  230. Process_Detach = 0, // About to unload DLL
  231. Process_Attach = 1, // Entry point
  232. Thread_Attach = 2,
  233. Thread_Detach = 3,
  234. }
  235. dll_forward_reason: DLL_Forward_Reason
  236. dll_instance: rawptr
  237. }
  238. // IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it)
  239. Source_Code_Location :: struct {
  240. file_path: string,
  241. line, column: i32,
  242. procedure: string,
  243. }
  244. /*
  245. Used by the built-in directory `#load_directory(path: string) -> []Load_Directory_File`
  246. */
  247. Load_Directory_File :: struct {
  248. name: string,
  249. data: []byte, // immutable data
  250. }
  251. Assertion_Failure_Proc :: #type proc(prefix, message: string, loc: Source_Code_Location) -> !
  252. // Allocation Stuff
  253. Allocator_Mode :: enum byte {
  254. Alloc,
  255. Free,
  256. Free_All,
  257. Resize,
  258. Query_Features,
  259. Query_Info,
  260. Alloc_Non_Zeroed,
  261. Resize_Non_Zeroed,
  262. }
  263. Allocator_Mode_Set :: distinct bit_set[Allocator_Mode]
  264. Allocator_Query_Info :: struct {
  265. pointer: rawptr,
  266. size: Maybe(int),
  267. alignment: Maybe(int),
  268. }
  269. Allocator_Error :: enum byte {
  270. None = 0,
  271. Out_Of_Memory = 1,
  272. Invalid_Pointer = 2,
  273. Invalid_Argument = 3,
  274. Mode_Not_Implemented = 4,
  275. }
  276. Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode,
  277. size, alignment: int,
  278. old_memory: rawptr, old_size: int,
  279. location: Source_Code_Location = #caller_location) -> ([]byte, Allocator_Error)
  280. Allocator :: struct {
  281. procedure: Allocator_Proc,
  282. data: rawptr,
  283. }
  284. Byte :: 1
  285. Kilobyte :: 1024 * Byte
  286. Megabyte :: 1024 * Kilobyte
  287. Gigabyte :: 1024 * Megabyte
  288. Terabyte :: 1024 * Gigabyte
  289. Petabyte :: 1024 * Terabyte
  290. Exabyte :: 1024 * Petabyte
  291. // Logging stuff
  292. Logger_Level :: enum uint {
  293. Debug = 0,
  294. Info = 10,
  295. Warning = 20,
  296. Error = 30,
  297. Fatal = 40,
  298. }
  299. Logger_Option :: enum {
  300. Level,
  301. Date,
  302. Time,
  303. Short_File_Path,
  304. Long_File_Path,
  305. Line,
  306. Procedure,
  307. Terminal_Color,
  308. Thread_Id,
  309. }
  310. Logger_Options :: bit_set[Logger_Option]
  311. Logger_Proc :: #type proc(data: rawptr, level: Logger_Level, text: string, options: Logger_Options, location := #caller_location)
  312. Logger :: struct {
  313. procedure: Logger_Proc,
  314. data: rawptr,
  315. lowest_level: Logger_Level,
  316. options: Logger_Options,
  317. }
  318. Random_Generator_Mode :: enum {
  319. Read,
  320. Reset,
  321. Query_Info,
  322. }
  323. Random_Generator_Query_Info_Flag :: enum u32 {
  324. Cryptographic,
  325. Uniform,
  326. External_Entropy,
  327. Resettable,
  328. }
  329. Random_Generator_Query_Info :: distinct bit_set[Random_Generator_Query_Info_Flag; u32]
  330. Random_Generator_Proc :: #type proc(data: rawptr, mode: Random_Generator_Mode, p: []byte)
  331. Random_Generator :: struct {
  332. procedure: Random_Generator_Proc,
  333. data: rawptr,
  334. }
  335. Context :: struct {
  336. allocator: Allocator,
  337. temp_allocator: Allocator,
  338. assertion_failure_proc: Assertion_Failure_Proc,
  339. logger: Logger,
  340. random_generator: Random_Generator,
  341. user_ptr: rawptr,
  342. user_index: int,
  343. // Internal use only
  344. _internal: rawptr,
  345. }
  346. Raw_String :: struct {
  347. data: [^]byte,
  348. len: int,
  349. }
  350. Raw_String16 :: struct {
  351. data: [^]u16,
  352. len: int,
  353. }
  354. Raw_Slice :: struct {
  355. data: rawptr,
  356. len: int,
  357. }
  358. Raw_Dynamic_Array :: struct {
  359. data: rawptr,
  360. len: int,
  361. cap: int,
  362. allocator: Allocator,
  363. }
  364. // The raw, type-erased representation of a map.
  365. //
  366. // 32-bytes on 64-bit
  367. // 16-bytes on 32-bit
  368. Raw_Map :: struct {
  369. // A single allocation spanning all keys, values, and hashes.
  370. // {
  371. // k: Map_Cell(K) * (capacity / ks_per_cell)
  372. // v: Map_Cell(V) * (capacity / vs_per_cell)
  373. // h: Map_Cell(H) * (capacity / hs_per_cell)
  374. // }
  375. //
  376. // The data is allocated assuming 64-byte alignment, meaning the address is
  377. // always a multiple of 64. This means we have 6 bits of zeros in the pointer
  378. // to store the capacity. We can store a value as large as 2^6-1 or 63 in
  379. // there. This conveniently is the maximum log2 capacity we can have for a map
  380. // as Odin uses signed integers to represent capacity.
  381. //
  382. // Since the hashes are backed by Map_Hash, which is just a 64-bit unsigned
  383. // integer, the cell structure for hashes is unnecessary because 64/8 is 8 and
  384. // requires no padding, meaning it can be indexed as a regular array of
  385. // Map_Hash directly, though for consistency sake it's written as if it were
  386. // an array of Map_Cell(Map_Hash).
  387. data: uintptr, // 8-bytes on 64-bits, 4-bytes on 32-bits
  388. len: uintptr, // 8-bytes on 64-bits, 4-bytes on 32-bits
  389. allocator: Allocator, // 16-bytes on 64-bits, 8-bytes on 32-bits
  390. }
  391. Raw_Any :: struct {
  392. data: rawptr,
  393. id: typeid,
  394. }
  395. when !ODIN_NO_RTTI {
  396. #assert(size_of(Raw_Any) == size_of(any))
  397. }
  398. Raw_Cstring :: struct {
  399. data: [^]byte,
  400. }
  401. #assert(size_of(Raw_Cstring) == size_of(cstring))
  402. Raw_Cstring16 :: struct {
  403. data: [^]u16,
  404. }
  405. #assert(size_of(Raw_Cstring16) == size_of(cstring16))
  406. Raw_Soa_Pointer :: struct {
  407. data: rawptr,
  408. index: int,
  409. }
  410. Raw_Complex32 :: struct {real, imag: f16}
  411. Raw_Complex64 :: struct {real, imag: f32}
  412. Raw_Complex128 :: struct {real, imag: f64}
  413. Raw_Quaternion64 :: struct {imag, jmag, kmag: f16, real: f16}
  414. Raw_Quaternion128 :: struct {imag, jmag, kmag: f32, real: f32}
  415. Raw_Quaternion256 :: struct {imag, jmag, kmag: f64, real: f64}
  416. Raw_Quaternion64_Vector_Scalar :: struct {vector: [3]f16, scalar: f16}
  417. Raw_Quaternion128_Vector_Scalar :: struct {vector: [3]f32, scalar: f32}
  418. Raw_Quaternion256_Vector_Scalar :: struct {vector: [3]f64, scalar: f64}
  419. /*
  420. // Defined internally by the compiler
  421. Odin_OS_Type :: enum int {
  422. Unknown,
  423. Windows,
  424. Darwin,
  425. Linux,
  426. Essence,
  427. FreeBSD,
  428. OpenBSD,
  429. NetBSD,
  430. Haiku,
  431. WASI,
  432. JS,
  433. Orca,
  434. Freestanding,
  435. }
  436. */
  437. Odin_OS_Type :: type_of(ODIN_OS)
  438. /*
  439. // Defined internally by the compiler
  440. Odin_Arch_Type :: enum int {
  441. Unknown,
  442. amd64,
  443. i386,
  444. arm32,
  445. arm64,
  446. wasm32,
  447. wasm64p32,
  448. riscv64,
  449. }
  450. */
  451. Odin_Arch_Type :: type_of(ODIN_ARCH)
  452. Odin_Arch_Types :: bit_set[Odin_Arch_Type]
  453. ALL_ODIN_ARCH_TYPES :: Odin_Arch_Types{
  454. .amd64,
  455. .i386,
  456. .arm32,
  457. .arm64,
  458. .wasm32,
  459. .wasm64p32,
  460. .riscv64,
  461. }
  462. /*
  463. // Defined internally by the compiler
  464. Odin_Build_Mode_Type :: enum int {
  465. Executable,
  466. Dynamic,
  467. Static,
  468. Object,
  469. Assembly,
  470. LLVM_IR,
  471. }
  472. */
  473. Odin_Build_Mode_Type :: type_of(ODIN_BUILD_MODE)
  474. /*
  475. // Defined internally by the compiler
  476. Odin_Endian_Type :: enum int {
  477. Unknown,
  478. Little,
  479. Big,
  480. }
  481. */
  482. Odin_Endian_Type :: type_of(ODIN_ENDIAN)
  483. Odin_OS_Types :: bit_set[Odin_OS_Type]
  484. ALL_ODIN_OS_TYPES :: Odin_OS_Types{
  485. .Windows,
  486. .Darwin,
  487. .Linux,
  488. .Essence,
  489. .FreeBSD,
  490. .OpenBSD,
  491. .NetBSD,
  492. .Haiku,
  493. .WASI,
  494. .JS,
  495. .Orca,
  496. .Freestanding,
  497. }
  498. /*
  499. // Defined internally by the compiler
  500. Odin_Platform_Subtarget_Type :: enum int {
  501. Default,
  502. iPhone,
  503. iPhoneSimulator
  504. Android,
  505. }
  506. */
  507. Odin_Platform_Subtarget_Type :: type_of(ODIN_PLATFORM_SUBTARGET)
  508. Odin_Platform_Subtarget_Types :: bit_set[Odin_Platform_Subtarget_Type]
  509. @(builtin)
  510. ODIN_PLATFORM_SUBTARGET_IOS :: ODIN_PLATFORM_SUBTARGET == .iPhone || ODIN_PLATFORM_SUBTARGET == .iPhoneSimulator
  511. /*
  512. // Defined internally by the compiler
  513. Odin_Sanitizer_Flag :: enum u32 {
  514. Address = 0,
  515. Memory = 1,
  516. Thread = 2,
  517. }
  518. Odin_Sanitizer_Flags :: distinct bit_set[Odin_Sanitizer_Flag; u32]
  519. ODIN_SANITIZER_FLAGS // is a constant
  520. */
  521. Odin_Sanitizer_Flags :: type_of(ODIN_SANITIZER_FLAGS)
  522. /*
  523. // Defined internally by the compiler
  524. Odin_Optimization_Mode :: enum int {
  525. None = -1,
  526. Minimal = 0,
  527. Size = 1,
  528. Speed = 2,
  529. Aggressive = 3,
  530. }
  531. ODIN_OPTIMIZATION_MODE // is a constant
  532. */
  533. Odin_Optimization_Mode :: type_of(ODIN_OPTIMIZATION_MODE)
  534. /////////////////////////////
  535. // Init Startup Procedures //
  536. /////////////////////////////
  537. // IMPORTANT NOTE(bill): Do not call this unless you want to explicitly set up the entry point and how it gets called
  538. // This is probably only useful for freestanding targets
  539. foreign {
  540. @(link_name="__$startup_runtime")
  541. _startup_runtime :: proc "odin" () ---
  542. @(link_name="__$cleanup_runtime")
  543. _cleanup_runtime :: proc "odin" () ---
  544. }
  545. _cleanup_runtime_contextless :: proc "contextless" () {
  546. context = default_context()
  547. _cleanup_runtime()
  548. }
  549. /////////////////////////////
  550. /////////////////////////////
  551. /////////////////////////////
  552. type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
  553. if info == nil {
  554. return nil
  555. }
  556. base := info
  557. loop: for {
  558. #partial switch i in base.variant {
  559. case Type_Info_Named: base = i.base
  560. case: break loop
  561. }
  562. }
  563. return base
  564. }
  565. type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
  566. if info == nil {
  567. return nil
  568. }
  569. base := info
  570. loop: for {
  571. #partial switch i in base.variant {
  572. case Type_Info_Named: base = i.base
  573. case Type_Info_Enum: base = i.base
  574. case Type_Info_Bit_Field: base = i.backing_type
  575. case: break loop
  576. }
  577. }
  578. return base
  579. }
  580. type_info_base_without_enum :: type_info_core
  581. __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info #no_bounds_check {
  582. n := u64(len(type_table))
  583. i := transmute(u64)id % n
  584. for _ in 0..<n {
  585. ptr := type_table[i]
  586. if ptr != nil && ptr.id == id {
  587. return ptr
  588. }
  589. i = i+1 if i+1 < n else 0
  590. }
  591. return type_table[0]
  592. }
  593. when !ODIN_NO_RTTI {
  594. typeid_base :: proc "contextless" (id: typeid) -> typeid {
  595. ti := type_info_of(id)
  596. ti = type_info_base(ti)
  597. return ti.id
  598. }
  599. typeid_core :: proc "contextless" (id: typeid) -> typeid {
  600. ti := type_info_core(type_info_of(id))
  601. return ti.id
  602. }
  603. typeid_base_without_enum :: typeid_core
  604. }
  605. debug_trap :: intrinsics.debug_trap
  606. trap :: intrinsics.trap
  607. read_cycle_counter :: intrinsics.read_cycle_counter
  608. default_logger_proc :: proc(data: rawptr, level: Logger_Level, text: string, options: Logger_Options, location := #caller_location) {
  609. // Nothing
  610. }
  611. default_logger :: proc() -> Logger {
  612. return Logger{default_logger_proc, nil, Logger_Level.Debug, nil}
  613. }
  614. default_context :: proc "contextless" () -> Context {
  615. c: Context
  616. __init_context(&c)
  617. return c
  618. }
  619. @private
  620. __init_context_from_ptr :: proc "contextless" (c: ^Context, other: ^Context) {
  621. if c == nil {
  622. return
  623. }
  624. c^ = other^
  625. __init_context(c)
  626. }
  627. @private
  628. __init_context :: proc "contextless" (c: ^Context) {
  629. if c == nil {
  630. return
  631. }
  632. // NOTE(bill): Do not initialize these procedures with a call as they are not defined with the "contextless" calling convention
  633. c.allocator.procedure = default_allocator_proc
  634. c.allocator.data = nil
  635. c.temp_allocator.procedure = default_temp_allocator_proc
  636. when !NO_DEFAULT_TEMP_ALLOCATOR {
  637. c.temp_allocator.data = &global_default_temp_allocator_data
  638. }
  639. when !ODIN_DISABLE_ASSERT {
  640. c.assertion_failure_proc = default_assertion_failure_proc
  641. }
  642. c.logger.procedure = default_logger_proc
  643. c.logger.data = nil
  644. c.random_generator.procedure = default_random_generator_proc
  645. c.random_generator.data = nil
  646. }
  647. default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code_Location) -> ! {
  648. default_assertion_contextless_failure_proc(prefix, message, loc)
  649. }
  650. default_assertion_contextless_failure_proc :: proc "contextless" (prefix, message: string, loc: Source_Code_Location) -> ! {
  651. when ODIN_OS == .Freestanding {
  652. // Do nothing
  653. } else {
  654. when ODIN_OS != .Orca && !ODIN_DISABLE_ASSERT {
  655. print_caller_location(loc)
  656. print_string(" ")
  657. }
  658. print_string(prefix)
  659. if len(message) > 0 {
  660. print_string(": ")
  661. print_string(message)
  662. }
  663. when ODIN_OS == .Orca {
  664. assert_fail(
  665. cstring(raw_data(loc.file_path)),
  666. cstring(raw_data(loc.procedure)),
  667. loc.line,
  668. "",
  669. cstring(raw_data(orca_stderr_buffer[:orca_stderr_buffer_idx])),
  670. )
  671. } else {
  672. print_byte('\n')
  673. }
  674. }
  675. trap()
  676. }