core.odin 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569
  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. package runtime
  5. import "core:os"
  6. import "intrinsics"
  7. _ :: intrinsics;
  8. // Naming Conventions:
  9. // In general, Ada_Case for types and snake_case for values
  10. //
  11. // Package Name: snake_case (but prefer single word)
  12. // Import Name: snake_case (but prefer single word)
  13. // Types: Ada_Case
  14. // Enum Values: Ada_Case
  15. // Procedures: snake_case
  16. // Local Variables: snake_case
  17. // Constant Variables: SCREAMING_SNAKE_CASE
  18. // IMPORTANT NOTE(bill): `type_info_of` cannot be used within a
  19. // #shared_global_scope due to the internals of the compiler.
  20. // This could change at a later date if the all these data structures are
  21. // implemented within the compiler rather than in this "preload" file
  22. // NOTE(bill): This must match the compiler's
  23. Calling_Convention :: enum u8 {
  24. Invalid = 0,
  25. Odin = 1,
  26. Contextless = 2,
  27. C = 3,
  28. Std = 4,
  29. Fast = 5,
  30. }
  31. Type_Info_Enum_Value :: distinct i64;
  32. Platform_Endianness :: enum u8 {
  33. Platform = 0,
  34. Little = 1,
  35. Big = 2,
  36. }
  37. Type_Info_Struct_Soa_Kind :: enum u8 {
  38. None = 0,
  39. Fixed = 1,
  40. Slice = 2,
  41. Dynamic = 3,
  42. }
  43. // Variant Types
  44. Type_Info_Named :: struct {name: string, base: ^Type_Info};
  45. Type_Info_Integer :: struct {signed: bool, endianness: Platform_Endianness};
  46. Type_Info_Rune :: struct {};
  47. Type_Info_Float :: struct {endianness: Platform_Endianness};
  48. Type_Info_Complex :: struct {};
  49. Type_Info_Quaternion :: struct {};
  50. Type_Info_String :: struct {is_cstring: bool};
  51. Type_Info_Boolean :: struct {};
  52. Type_Info_Any :: struct {};
  53. Type_Info_Type_Id :: struct {};
  54. Type_Info_Pointer :: struct {
  55. elem: ^Type_Info // nil -> rawptr
  56. };
  57. Type_Info_Procedure :: struct {
  58. params: ^Type_Info, // Type_Info_Tuple
  59. results: ^Type_Info, // Type_Info_Tuple
  60. variadic: bool,
  61. convention: Calling_Convention,
  62. };
  63. Type_Info_Array :: struct {
  64. elem: ^Type_Info,
  65. elem_size: int,
  66. count: int,
  67. };
  68. Type_Info_Enumerated_Array :: struct {
  69. elem: ^Type_Info,
  70. index: ^Type_Info,
  71. elem_size: int,
  72. count: int,
  73. min_value: Type_Info_Enum_Value,
  74. max_value: Type_Info_Enum_Value,
  75. };
  76. Type_Info_Dynamic_Array :: struct {elem: ^Type_Info, elem_size: int};
  77. Type_Info_Slice :: struct {elem: ^Type_Info, elem_size: int};
  78. Type_Info_Tuple :: struct { // Only really used for procedures
  79. types: []^Type_Info,
  80. names: []string,
  81. };
  82. Type_Info_Struct :: struct {
  83. types: []^Type_Info,
  84. names: []string,
  85. offsets: []uintptr,
  86. usings: []bool,
  87. tags: []string,
  88. is_packed: bool,
  89. is_raw_union: bool,
  90. custom_align: bool,
  91. // These are only set iff this structure is an SOA structure
  92. soa_kind: Type_Info_Struct_Soa_Kind,
  93. soa_base_type: ^Type_Info,
  94. soa_len: int,
  95. };
  96. Type_Info_Union :: struct {
  97. variants: []^Type_Info,
  98. tag_offset: uintptr,
  99. tag_type: ^Type_Info,
  100. custom_align: bool,
  101. no_nil: bool,
  102. maybe: bool,
  103. };
  104. Type_Info_Enum :: struct {
  105. base: ^Type_Info,
  106. names: []string,
  107. values: []Type_Info_Enum_Value,
  108. };
  109. Type_Info_Map :: struct {
  110. key: ^Type_Info,
  111. value: ^Type_Info,
  112. generated_struct: ^Type_Info,
  113. };
  114. Type_Info_Bit_Field :: struct {
  115. names: []string,
  116. bits: []i32,
  117. offsets: []i32,
  118. };
  119. Type_Info_Bit_Set :: struct {
  120. elem: ^Type_Info,
  121. underlying: ^Type_Info, // Possibly nil
  122. lower: i64,
  123. upper: i64,
  124. };
  125. Type_Info_Opaque :: struct {
  126. elem: ^Type_Info,
  127. };
  128. Type_Info_Simd_Vector :: struct {
  129. elem: ^Type_Info,
  130. elem_size: int,
  131. count: int,
  132. is_x86_mmx: bool,
  133. };
  134. Type_Info_Relative_Pointer :: struct {
  135. pointer: ^Type_Info,
  136. base_integer: ^Type_Info,
  137. };
  138. Type_Info_Relative_Slice :: struct {
  139. slice: ^Type_Info,
  140. base_integer: ^Type_Info,
  141. };
  142. Type_Info :: struct {
  143. size: int,
  144. align: int,
  145. id: typeid,
  146. variant: union {
  147. Type_Info_Named,
  148. Type_Info_Integer,
  149. Type_Info_Rune,
  150. Type_Info_Float,
  151. Type_Info_Complex,
  152. Type_Info_Quaternion,
  153. Type_Info_String,
  154. Type_Info_Boolean,
  155. Type_Info_Any,
  156. Type_Info_Type_Id,
  157. Type_Info_Pointer,
  158. Type_Info_Procedure,
  159. Type_Info_Array,
  160. Type_Info_Enumerated_Array,
  161. Type_Info_Dynamic_Array,
  162. Type_Info_Slice,
  163. Type_Info_Tuple,
  164. Type_Info_Struct,
  165. Type_Info_Union,
  166. Type_Info_Enum,
  167. Type_Info_Map,
  168. Type_Info_Bit_Field,
  169. Type_Info_Bit_Set,
  170. Type_Info_Opaque,
  171. Type_Info_Simd_Vector,
  172. Type_Info_Relative_Pointer,
  173. Type_Info_Relative_Slice,
  174. },
  175. }
  176. // NOTE(bill): This must match the compiler's
  177. Typeid_Kind :: enum u8 {
  178. Invalid,
  179. Integer,
  180. Rune,
  181. Float,
  182. Complex,
  183. Quaternion,
  184. String,
  185. Boolean,
  186. Any,
  187. Type_Id,
  188. Pointer,
  189. Procedure,
  190. Array,
  191. Enumerated_Array,
  192. Dynamic_Array,
  193. Slice,
  194. Tuple,
  195. Struct,
  196. Union,
  197. Enum,
  198. Map,
  199. Bit_Field,
  200. Bit_Set,
  201. Opaque,
  202. Simd_Vector,
  203. Relative_Pointer,
  204. Relative_Slice,
  205. }
  206. #assert(len(Typeid_Kind) < 32);
  207. Typeid_Bit_Field :: bit_field #align align_of(uintptr) {
  208. index: 8*size_of(uintptr) - 8,
  209. kind: 5, // Typeid_Kind
  210. named: 1,
  211. special: 1, // signed, cstring, etc
  212. reserved: 1,
  213. }
  214. #assert(size_of(Typeid_Bit_Field) == size_of(uintptr));
  215. // NOTE(bill): only the ones that are needed (not all types)
  216. // This will be set by the compiler
  217. type_table: []Type_Info;
  218. args__: []cstring;
  219. // IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it)
  220. @builtin
  221. Maybe :: union(T: typeid) #maybe {T};
  222. Source_Code_Location :: struct {
  223. file_path: string,
  224. line, column: int,
  225. procedure: string,
  226. hash: u64,
  227. }
  228. Assertion_Failure_Proc :: #type proc(prefix, message: string, loc: Source_Code_Location);
  229. // Allocation Stuff
  230. Allocator_Mode :: enum byte {
  231. Alloc,
  232. Free,
  233. Free_All,
  234. Resize,
  235. Query_Features,
  236. Query_Info,
  237. }
  238. Allocator_Mode_Set :: distinct bit_set[Allocator_Mode];
  239. Allocator_Query_Info :: struct {
  240. pointer: rawptr,
  241. size: Maybe(int),
  242. alignment: Maybe(int),
  243. }
  244. Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode,
  245. size, alignment: int,
  246. old_memory: rawptr, old_size: int, flags: u64 = 0, location: Source_Code_Location = #caller_location) -> rawptr;
  247. Allocator :: struct {
  248. procedure: Allocator_Proc,
  249. data: rawptr,
  250. }
  251. // Logging stuff
  252. Logger_Level :: enum uint {
  253. Debug = 0,
  254. Info = 10,
  255. Warning = 20,
  256. Error = 30,
  257. Fatal = 40,
  258. }
  259. Logger_Option :: enum {
  260. Level,
  261. Date,
  262. Time,
  263. Short_File_Path,
  264. Long_File_Path,
  265. Line,
  266. Procedure,
  267. Terminal_Color,
  268. Thread_Id
  269. }
  270. Logger_Options :: bit_set[Logger_Option];
  271. Logger_Proc :: #type proc(data: rawptr, level: Logger_Level, text: string, options: Logger_Options, location := #caller_location);
  272. Logger :: struct {
  273. procedure: Logger_Proc,
  274. data: rawptr,
  275. lowest_level: Logger_Level,
  276. options: Logger_Options,
  277. }
  278. Context :: struct {
  279. allocator: Allocator,
  280. temp_allocator: Allocator,
  281. assertion_failure_proc: Assertion_Failure_Proc,
  282. logger: Logger,
  283. thread_id: int,
  284. user_data: any,
  285. user_ptr: rawptr,
  286. user_index: int,
  287. }
  288. @thread_local global_default_temp_allocator_data: Default_Temp_Allocator;
  289. Raw_String :: struct {
  290. data: ^byte,
  291. len: int,
  292. }
  293. Raw_Slice :: struct {
  294. data: rawptr,
  295. len: int,
  296. }
  297. Raw_Dynamic_Array :: struct {
  298. data: rawptr,
  299. len: int,
  300. cap: int,
  301. allocator: Allocator,
  302. }
  303. Raw_Map :: struct {
  304. hashes: []int,
  305. entries: Raw_Dynamic_Array,
  306. }
  307. INITIAL_MAP_CAP :: 16;
  308. Map_Key :: struct {
  309. hash: u64,
  310. str: string,
  311. }
  312. Map_Find_Result :: struct {
  313. hash_index: int,
  314. entry_prev: int,
  315. entry_index: int,
  316. }
  317. Map_Entry_Header :: struct {
  318. key: Map_Key,
  319. next: int,
  320. /*
  321. value: Value_Type,
  322. */
  323. }
  324. Map_Header :: struct {
  325. m: ^Raw_Map,
  326. is_key_string: bool,
  327. entry_size: int,
  328. entry_align: int,
  329. value_offset: uintptr,
  330. value_size: int,
  331. }
  332. type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
  333. if info == nil do return nil;
  334. base := info;
  335. loop: for {
  336. #partial switch i in base.variant {
  337. case Type_Info_Named: base = i.base;
  338. case: break loop;
  339. }
  340. }
  341. return base;
  342. }
  343. type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
  344. if info == nil do return nil;
  345. base := info;
  346. loop: for {
  347. #partial switch i in base.variant {
  348. case Type_Info_Named: base = i.base;
  349. case Type_Info_Enum: base = i.base;
  350. case Type_Info_Opaque: base = i.elem;
  351. case: break loop;
  352. }
  353. }
  354. return base;
  355. }
  356. type_info_base_without_enum :: type_info_core;
  357. __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info {
  358. data := transmute(Typeid_Bit_Field)id;
  359. n := int(data.index);
  360. if n < 0 || n >= len(type_table) {
  361. n = 0;
  362. }
  363. return &type_table[n];
  364. }
  365. typeid_base :: proc "contextless" (id: typeid) -> typeid {
  366. ti := type_info_of(id);
  367. ti = type_info_base(ti);
  368. return ti.id;
  369. }
  370. typeid_core :: proc "contextless" (id: typeid) -> typeid {
  371. ti := type_info_base_without_enum(type_info_of(id));
  372. return ti.id;
  373. }
  374. typeid_base_without_enum :: typeid_core;
  375. @(default_calling_convention = "none")
  376. foreign {
  377. @(link_name="llvm.assume")
  378. assume :: proc(cond: bool) ---;
  379. @(link_name="llvm.debugtrap")
  380. debug_trap :: proc() ---;
  381. @(link_name="llvm.trap")
  382. trap :: proc() -> ! ---;
  383. @(link_name="llvm.readcyclecounter")
  384. read_cycle_counter :: proc() -> u64 ---;
  385. }
  386. default_logger_proc :: proc(data: rawptr, level: Logger_Level, text: string, options: Logger_Options, location := #caller_location) {
  387. // Do nothing
  388. }
  389. default_logger :: proc() -> Logger {
  390. return Logger{default_logger_proc, nil, Logger_Level.Debug, nil};
  391. }
  392. default_context :: proc "contextless" () -> Context {
  393. c: Context;
  394. __init_context(&c);
  395. return c;
  396. }
  397. @private
  398. __init_context_from_ptr :: proc "contextless" (c: ^Context, other: ^Context) {
  399. if c == nil do return;
  400. c^ = other^;
  401. __init_context(c);
  402. }
  403. @private
  404. __init_context :: proc "contextless" (c: ^Context) {
  405. if c == nil do return;
  406. // NOTE(bill): Do not initialize these procedures with a call as they are not defined with the "contexless" calling convention
  407. c.allocator.procedure = default_allocator_proc;
  408. c.allocator.data = nil;
  409. c.temp_allocator.procedure = default_temp_allocator_proc;
  410. c.temp_allocator.data = &global_default_temp_allocator_data;
  411. c.thread_id = os.current_thread_id(); // NOTE(bill): This is "contextless" so it is okay to call
  412. c.assertion_failure_proc = default_assertion_failure_proc;
  413. c.logger.procedure = default_logger_proc;
  414. c.logger.data = nil;
  415. // c.stdin = os.stdin;
  416. // c.stdout = os.stdout;
  417. // c.stderr = os.stderr;
  418. }
  419. @builtin
  420. init_global_temporary_allocator :: proc(data: []byte, backup_allocator := context.allocator) {
  421. default_temp_allocator_init(&global_default_temp_allocator_data, data, backup_allocator);
  422. }
  423. default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code_Location) {
  424. fd := os.stderr;
  425. print_caller_location(fd, loc);
  426. os.write_string(fd, " ");
  427. os.write_string(fd, prefix);
  428. if len(message) > 0 {
  429. os.write_string(fd, ": ");
  430. os.write_string(fd, message);
  431. }
  432. os.write_byte(fd, '\n');
  433. debug_trap();
  434. }
  435. @builtin
  436. copy_slice :: proc "contextless" (dst, src: $T/[]$E) -> int {
  437. n := max(0, min(len(dst), len(src)));
  438. if n > 0 {
  439. mem_copy(raw_data(dst), raw_data(src), n*size_of(E));
  440. }
  441. return n;
  442. }
  443. @builtin
  444. copy_from_string :: proc "contextless" (dst: $T/[]$E/u8, src: $S/string) -> int {
  445. n := max(0, min(len(dst), len(src)));
  446. if n > 0 {
  447. mem_copy(raw_data(dst), raw_data(src), n);
  448. }
  449. return n;
  450. }
  451. @builtin
  452. copy :: proc{copy_slice, copy_from_string};
  453. @builtin
  454. unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) {
  455. bounds_check_error_loc(loc, index, len(array));
  456. n := len(array)-1;
  457. if index != n {
  458. array[index] = array[n];
  459. }
  460. pop(array);
  461. }
  462. @builtin
  463. ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) {
  464. bounds_check_error_loc(loc, index, len(array));
  465. if index+1 < len(array) {
  466. copy(array[index:], array[index+1:]);
  467. }
  468. pop(array);
  469. }
  470. @builtin
  471. pop :: proc(array: ^$T/[dynamic]$E) -> E {
  472. if len(array) == 0 {
  473. return E{};
  474. }
  475. assert(len(array) > 0);
  476. res := #no_bounds_check array[len(array)-1];
  477. (^Raw_Dynamic_Array)(array).len -= 1;
  478. return res;
  479. }
  480. @builtin
  481. pop_safe :: proc(array: ^$T/[dynamic]$E) -> (E, bool) {
  482. if len(array) == 0 {
  483. return E{}, false;
  484. }
  485. res := #no_bounds_check array[len(array)-1];
  486. (^Raw_Dynamic_Array)(array).len -= 1;
  487. return res, true;
  488. }
  489. @builtin
  490. pop_front :: proc(array: ^$T/[dynamic]$E) -> E #no_bounds_check {
  491. assert(len(array) > 0);
  492. res := array[0];
  493. if len(array) > 1 {
  494. copy(array[0:], array[1:]);
  495. }
  496. (^Raw_Dynamic_Array)(array).len -= 1;
  497. return res;
  498. }
  499. @builtin
  500. pop_front_safe :: proc(array: ^$T/[dynamic]$E) -> (E, bool) #no_bounds_check {
  501. if len(array) == 0 {
  502. return E{}, false;
  503. }
  504. res := array[0];
  505. if len(array) > 1 {
  506. copy(array[0:], array[1:]);
  507. }
  508. (^Raw_Dynamic_Array)(array).len -= 1;
  509. return res, true;
  510. }
  511. @builtin
  512. clear :: proc{clear_dynamic_array, clear_map};
  513. @builtin
  514. reserve :: proc{reserve_dynamic_array, reserve_map};
  515. @builtin
  516. resize :: proc{resize_dynamic_array};
  517. @builtin
  518. free :: proc{mem_free};
  519. @builtin
  520. free_all :: proc{mem_free_all};
  521. @builtin
  522. delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) {
  523. mem_free(raw_data(str), allocator, loc);
  524. }
  525. @builtin
  526. delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) {
  527. mem_free((^byte)(str), allocator, loc);
  528. }
  529. @builtin
  530. delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) {
  531. mem_free(raw_data(array), array.allocator, loc);
  532. }
  533. @builtin
  534. delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) {
  535. mem_free(raw_data(array), allocator, loc);
  536. }
  537. @builtin
  538. delete_map :: proc(m: $T/map[$K]$V, loc := #caller_location) {
  539. raw := transmute(Raw_Map)m;
  540. delete_slice(raw.hashes);
  541. mem_free(raw.entries.data, raw.entries.allocator, loc);
  542. }
  543. @builtin
  544. delete :: proc{
  545. delete_string,
  546. delete_cstring,
  547. delete_dynamic_array,
  548. delete_slice,
  549. delete_map,
  550. };
  551. @builtin
  552. new :: inline proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> ^T {
  553. ptr := (^T)(mem_alloc(size_of(T), align_of(T), allocator, loc));
  554. if ptr != nil do ptr^ = T{};
  555. return ptr;
  556. }
  557. @builtin
  558. new_clone :: inline proc(data: $T, allocator := context.allocator, loc := #caller_location) -> ^T {
  559. ptr := (^T)(mem_alloc(size_of(T), align_of(T), allocator, loc));
  560. if ptr != nil do ptr^ = data;
  561. return ptr;
  562. }
  563. make_aligned :: proc($T: typeid/[]$E, auto_cast len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> T {
  564. make_slice_error_loc(loc, len);
  565. data := mem_alloc(size_of(E)*len, alignment, allocator, loc);
  566. if data == nil && size_of(E) != 0 {
  567. return nil;
  568. }
  569. // mem_zero(data, size_of(E)*len);
  570. s := Raw_Slice{data, len};
  571. return transmute(T)s;
  572. }
  573. @builtin
  574. make_slice :: inline proc($T: typeid/[]$E, auto_cast len: int, allocator := context.allocator, loc := #caller_location) -> T {
  575. return make_aligned(T, len, align_of(E), allocator, loc);
  576. }
  577. @builtin
  578. make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> T {
  579. return make_dynamic_array_len_cap(T, 0, 16, allocator, loc);
  580. }
  581. @builtin
  582. make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, auto_cast len: int, allocator := context.allocator, loc := #caller_location) -> T {
  583. return make_dynamic_array_len_cap(T, len, len, allocator, loc);
  584. }
  585. @builtin
  586. make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, auto_cast len: int, auto_cast cap: int, allocator := context.allocator, loc := #caller_location) -> T {
  587. make_dynamic_array_error_loc(loc, len, cap);
  588. data := mem_alloc(size_of(E)*cap, align_of(E), allocator, loc);
  589. s := Raw_Dynamic_Array{data, len, cap, allocator};
  590. if data == nil && size_of(E) != 0 {
  591. s.len, s.cap = 0, 0;
  592. }
  593. // mem_zero(data, size_of(E)*cap);
  594. return transmute(T)s;
  595. }
  596. @builtin
  597. make_map :: proc($T: typeid/map[$K]$E, auto_cast cap: int = 16, allocator := context.allocator, loc := #caller_location) -> T {
  598. make_map_expr_error_loc(loc, cap);
  599. context.allocator = allocator;
  600. m: T;
  601. reserve_map(&m, cap);
  602. return m;
  603. }
  604. @builtin
  605. make :: proc{
  606. make_slice,
  607. make_dynamic_array,
  608. make_dynamic_array_len,
  609. make_dynamic_array_len_cap,
  610. make_map,
  611. };
  612. @builtin
  613. clear_map :: inline proc "contextless" (m: ^$T/map[$K]$V) {
  614. if m == nil do return;
  615. raw_map := (^Raw_Map)(m);
  616. entries := (^Raw_Dynamic_Array)(&raw_map.entries);
  617. entries.len = 0;
  618. for _, i in raw_map.hashes {
  619. raw_map.hashes[i] = -1;
  620. }
  621. }
  622. @builtin
  623. reserve_map :: proc(m: ^$T/map[$K]$V, capacity: int) {
  624. if m != nil do __dynamic_map_reserve(__get_map_header(m), capacity);
  625. }
  626. @builtin
  627. delete_key :: proc(m: ^$T/map[$K]$V, key: K) {
  628. if m != nil do __dynamic_map_delete_key(__get_map_header(m), __get_map_key(key));
  629. }
  630. @builtin
  631. append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) {
  632. if array == nil do return;
  633. arg_len := 1;
  634. if cap(array) < len(array)+arg_len {
  635. cap := 2 * cap(array) + max(8, arg_len);
  636. _ = reserve(array, cap, loc);
  637. }
  638. arg_len = min(cap(array)-len(array), arg_len);
  639. if arg_len > 0 {
  640. a := (^Raw_Dynamic_Array)(array);
  641. if size_of(E) != 0 {
  642. data := (^E)(a.data);
  643. assert(data != nil);
  644. val := arg;
  645. mem_copy(ptr_offset(data, a.len), &val, size_of(E));
  646. }
  647. a.len += arg_len;
  648. }
  649. }
  650. @builtin
  651. append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) {
  652. if array == nil do return;
  653. arg_len := len(args);
  654. if arg_len <= 0 do return;
  655. if cap(array) < len(array)+arg_len {
  656. cap := 2 * cap(array) + max(8, arg_len);
  657. _ = reserve(array, cap, loc);
  658. }
  659. arg_len = min(cap(array)-len(array), arg_len);
  660. if arg_len > 0 {
  661. a := (^Raw_Dynamic_Array)(array);
  662. if size_of(E) != 0 {
  663. data := (^E)(a.data);
  664. assert(data != nil);
  665. mem_copy(ptr_offset(data, a.len), &args[0], size_of(E) * arg_len);
  666. }
  667. a.len += arg_len;
  668. }
  669. }
  670. @builtin
  671. append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) {
  672. args := transmute([]E)arg;
  673. append_elems(array=array, args=args, loc=loc);
  674. }
  675. @builtin
  676. reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
  677. if array == nil do return false;
  678. old_cap := cap(array);
  679. if capacity <= old_cap do return true;
  680. if array.allocator.procedure == nil {
  681. array.allocator = context.allocator;
  682. }
  683. assert(array.allocator.procedure != nil);
  684. ti := type_info_of(typeid_of(T));
  685. ti = type_info_base(ti);
  686. si := &ti.variant.(Type_Info_Struct);
  687. field_count := uintptr(len(si.offsets) - 3);
  688. if field_count == 0 {
  689. return true;
  690. }
  691. cap_ptr := cast(^int)rawptr(uintptr(array) + (field_count + 1)*size_of(rawptr));
  692. assert(cap_ptr^ == old_cap);
  693. old_size := 0;
  694. new_size := 0;
  695. max_align := 0;
  696. for i in 0..<field_count {
  697. type := si.types[i].variant.(Type_Info_Pointer).elem;
  698. max_align = max(max_align, type.align);
  699. old_size = align_forward_int(old_size, type.align);
  700. new_size = align_forward_int(new_size, type.align);
  701. old_size += type.size * old_cap;
  702. new_size += type.size * capacity;
  703. }
  704. old_size = align_forward_int(old_size, max_align);
  705. new_size = align_forward_int(new_size, max_align);
  706. old_data := (^rawptr)(array)^;
  707. new_data := array.allocator.procedure(
  708. array.allocator.data, .Alloc, new_size, max_align,
  709. nil, old_size, 0, loc,
  710. );
  711. if new_data == nil do return false;
  712. cap_ptr^ = capacity;
  713. old_offset := 0;
  714. new_offset := 0;
  715. for i in 0..<field_count {
  716. type := si.types[i].variant.(Type_Info_Pointer).elem;
  717. max_align = max(max_align, type.align);
  718. old_offset = align_forward_int(old_offset, type.align);
  719. new_offset = align_forward_int(new_offset, type.align);
  720. new_data_elem := rawptr(uintptr(new_data) + uintptr(new_offset));
  721. old_data_elem := rawptr(uintptr(old_data) + uintptr(old_offset));
  722. mem_copy(new_data_elem, old_data_elem, type.size * old_cap);
  723. (^rawptr)(uintptr(array) + i*size_of(rawptr))^ = new_data_elem;
  724. old_offset += type.size * old_cap;
  725. new_offset += type.size * capacity;
  726. }
  727. array.allocator.procedure(
  728. array.allocator.data, .Free, 0, max_align,
  729. old_data, old_size, 0, loc,
  730. );
  731. return true;
  732. }
  733. @builtin
  734. append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_location) {
  735. if array == nil do return;
  736. arg_len := 1;
  737. if cap(array) <= len(array)+arg_len {
  738. cap := 2 * cap(array) + max(8, arg_len);
  739. _ = reserve_soa(array, cap, loc);
  740. }
  741. arg_len = min(cap(array)-len(array), arg_len);
  742. if arg_len > 0 {
  743. ti := type_info_of(typeid_of(T));
  744. ti = type_info_base(ti);
  745. si := &ti.variant.(Type_Info_Struct);
  746. field_count := uintptr(len(si.offsets) - 3);
  747. if field_count == 0 {
  748. return;
  749. }
  750. data := (^rawptr)(array)^;
  751. len_ptr := cast(^int)rawptr(uintptr(array) + (field_count + 0)*size_of(rawptr));
  752. soa_offset := 0;
  753. item_offset := 0;
  754. arg_copy := arg;
  755. arg_ptr := &arg_copy;
  756. max_align := 0;
  757. for i in 0..<field_count {
  758. type := si.types[i].variant.(Type_Info_Pointer).elem;
  759. max_align = max(max_align, type.align);
  760. soa_offset = align_forward_int(soa_offset, type.align);
  761. item_offset = align_forward_int(item_offset, type.align);
  762. dst := rawptr(uintptr(data) + uintptr(soa_offset) + uintptr(type.size * len_ptr^));
  763. src := rawptr(uintptr(arg_ptr) + uintptr(item_offset));
  764. mem_copy(dst, src, type.size);
  765. soa_offset += type.size * cap(array);
  766. item_offset += type.size;
  767. }
  768. len_ptr^ += arg_len;
  769. }
  770. }
  771. @builtin
  772. append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_location) {
  773. if array == nil do return;
  774. arg_len := len(args);
  775. if arg_len == 0 {
  776. return;
  777. }
  778. if cap(array) <= len(array)+arg_len {
  779. cap := 2 * cap(array) + max(8, arg_len);
  780. _ = reserve_soa(array, cap, loc);
  781. }
  782. arg_len = min(cap(array)-len(array), arg_len);
  783. if arg_len > 0 {
  784. ti := type_info_of(typeid_of(T));
  785. ti = type_info_base(ti);
  786. si := &ti.variant.(Type_Info_Struct);
  787. field_count := uintptr(len(si.offsets) - 3);
  788. if field_count == 0 {
  789. return;
  790. }
  791. data := (^rawptr)(array)^;
  792. len_ptr := cast(^int)rawptr(uintptr(array) + (field_count + 0)*size_of(rawptr));
  793. soa_offset := 0;
  794. item_offset := 0;
  795. args_ptr := &args[0];
  796. max_align := 0;
  797. for i in 0..<field_count {
  798. type := si.types[i].variant.(Type_Info_Pointer).elem;
  799. max_align = max(max_align, type.align);
  800. soa_offset = align_forward_int(soa_offset, type.align);
  801. item_offset = align_forward_int(item_offset, type.align);
  802. dst := uintptr(data) + uintptr(soa_offset) + uintptr(type.size * len_ptr^);
  803. src := uintptr(args_ptr) + uintptr(item_offset);
  804. for j in 0..<arg_len {
  805. d := rawptr(dst + uintptr(j*type.size));
  806. s := rawptr(src + uintptr(j*size_of(E)));
  807. mem_copy(d, s, type.size);
  808. }
  809. soa_offset += type.size * cap(array);
  810. item_offset += type.size;
  811. }
  812. len_ptr^ += arg_len;
  813. }
  814. }
  815. @builtin append :: proc{append_elem, append_elems, append_elem_string};
  816. @builtin append_soa :: proc{append_soa_elem, append_soa_elems};
  817. @builtin
  818. append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) {
  819. for arg in args {
  820. append(array = array, args = transmute([]E)(arg), loc = loc);
  821. }
  822. }
  823. @builtin
  824. clear_dynamic_array :: inline proc "contextless" (array: ^$T/[dynamic]$E) {
  825. if array != nil do (^Raw_Dynamic_Array)(array).len = 0;
  826. }
  827. @builtin
  828. reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> bool {
  829. if array == nil do return false;
  830. a := (^Raw_Dynamic_Array)(array);
  831. if capacity <= a.cap do return true;
  832. if a.allocator.procedure == nil {
  833. a.allocator = context.allocator;
  834. }
  835. assert(a.allocator.procedure != nil);
  836. old_size := a.cap * size_of(E);
  837. new_size := capacity * size_of(E);
  838. allocator := a.allocator;
  839. new_data := allocator.procedure(
  840. allocator.data, .Resize, new_size, align_of(E),
  841. a.data, old_size, 0, loc,
  842. );
  843. if new_data == nil do return false;
  844. a.data = new_data;
  845. a.cap = capacity;
  846. return true;
  847. }
  848. @builtin
  849. resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> bool {
  850. if array == nil do return false;
  851. a := (^Raw_Dynamic_Array)(array);
  852. if length <= a.cap {
  853. a.len = max(length, 0);
  854. return true;
  855. }
  856. if a.allocator.procedure == nil {
  857. a.allocator = context.allocator;
  858. }
  859. assert(a.allocator.procedure != nil);
  860. old_size := a.cap * size_of(E);
  861. new_size := length * size_of(E);
  862. allocator := a.allocator;
  863. new_data := allocator.procedure(
  864. allocator.data, .Resize, new_size, align_of(E),
  865. a.data, old_size, 0, loc,
  866. );
  867. if new_data == nil do return false;
  868. a.data = new_data;
  869. a.len = length;
  870. a.cap = length;
  871. return true;
  872. }
  873. @builtin
  874. incl_elem :: inline proc(s: ^$S/bit_set[$E; $U], elem: E) -> S {
  875. s^ |= {elem};
  876. return s^;
  877. }
  878. @builtin
  879. incl_elems :: inline proc(s: ^$S/bit_set[$E; $U], elems: ..E) -> S {
  880. for elem in elems do s^ |= {elem};
  881. return s^;
  882. }
  883. @builtin
  884. incl_bit_set :: inline proc(s: ^$S/bit_set[$E; $U], other: S) -> S {
  885. s^ |= other;
  886. return s^;
  887. }
  888. @builtin
  889. excl_elem :: inline proc(s: ^$S/bit_set[$E; $U], elem: E) -> S {
  890. s^ &~= {elem};
  891. return s^;
  892. }
  893. @builtin
  894. excl_elems :: inline proc(s: ^$S/bit_set[$E; $U], elems: ..E) -> S {
  895. for elem in elems do s^ &~= {elem};
  896. return s^;
  897. }
  898. @builtin
  899. excl_bit_set :: inline proc(s: ^$S/bit_set[$E; $U], other: S) -> S {
  900. s^ &~= other;
  901. return s^;
  902. }
  903. @builtin incl :: proc{incl_elem, incl_elems, incl_bit_set};
  904. @builtin excl :: proc{excl_elem, excl_elems, excl_bit_set};
  905. @builtin
  906. card :: proc(s: $S/bit_set[$E; $U]) -> int {
  907. when size_of(S) == 1 {
  908. foreign { @(link_name="llvm.ctpop.i8") count_ones :: proc(i: u8) -> u8 --- }
  909. return int(count_ones(transmute(u8)s));
  910. } else when size_of(S) == 2 {
  911. foreign { @(link_name="llvm.ctpop.i16") count_ones :: proc(i: u16) -> u16 --- }
  912. return int(count_ones(transmute(u16)s));
  913. } else when size_of(S) == 4 {
  914. foreign { @(link_name="llvm.ctpop.i32") count_ones :: proc(i: u32) -> u32 --- }
  915. return int(count_ones(transmute(u32)s));
  916. } else when size_of(S) == 8 {
  917. foreign { @(link_name="llvm.ctpop.i64") count_ones :: proc(i: u64) -> u64 --- }
  918. return int(count_ones(transmute(u64)s));
  919. } else when size_of(S) == 16 {
  920. foreign { @(link_name="llvm.ctpop.i128") count_ones :: proc(i: u128) -> u128 --- }
  921. return int(count_ones(transmute(u128)s));
  922. } else {
  923. #assert(false);
  924. return 0;
  925. }
  926. }
  927. @builtin
  928. raw_array_data :: proc "contextless" (a: $P/^($T/[$N]$E)) -> ^E {
  929. return (^E)(a);
  930. }
  931. @builtin
  932. raw_slice_data :: proc "contextless" (s: $S/[]$E) -> ^E {
  933. ptr := (transmute(Raw_Slice)s).data;
  934. return (^E)(ptr);
  935. }
  936. @builtin
  937. raw_dynamic_array_data :: proc "contextless" (s: $S/[dynamic]$E) -> ^E {
  938. ptr := (transmute(Raw_Dynamic_Array)s).data;
  939. return (^E)(ptr);
  940. }
  941. @builtin
  942. raw_string_data :: proc "contextless" (s: $S/string) -> ^u8 {
  943. return (transmute(Raw_String)s).data;
  944. }
  945. @builtin
  946. raw_data :: proc{raw_array_data, raw_slice_data, raw_dynamic_array_data, raw_string_data};
  947. @builtin
  948. @(disabled=ODIN_DISABLE_ASSERT)
  949. assert :: proc(condition: bool, message := "", loc := #caller_location) {
  950. if !condition {
  951. proc(message: string, loc: Source_Code_Location) {
  952. p := context.assertion_failure_proc;
  953. if p == nil {
  954. p = default_assertion_failure_proc;
  955. }
  956. p("runtime assertion", message, loc);
  957. }(message, loc);
  958. }
  959. }
  960. @builtin
  961. @(disabled=ODIN_DISABLE_ASSERT)
  962. panic :: proc(message: string, loc := #caller_location) -> ! {
  963. p := context.assertion_failure_proc;
  964. if p == nil {
  965. p = default_assertion_failure_proc;
  966. }
  967. p("panic", message, loc);
  968. }
  969. @builtin
  970. @(disabled=ODIN_DISABLE_ASSERT)
  971. unimplemented :: proc(message := "", loc := #caller_location) -> ! {
  972. p := context.assertion_failure_proc;
  973. if p == nil {
  974. p = default_assertion_failure_proc;
  975. }
  976. p("not yet implemented", message, loc);
  977. }
  978. @builtin
  979. @(disabled=ODIN_DISABLE_ASSERT)
  980. unreachable :: proc(message := "", loc := #caller_location) -> ! {
  981. p := context.assertion_failure_proc;
  982. if p == nil {
  983. p = default_assertion_failure_proc;
  984. }
  985. if message != "" {
  986. p("internal error", message, loc);
  987. } else {
  988. p("internal error", "entered unreachable code", loc);
  989. }
  990. }
  991. // Dynamic Array
  992. __dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int, loc := #caller_location) {
  993. array := (^Raw_Dynamic_Array)(array_);
  994. array.allocator = context.allocator;
  995. assert(array.allocator.procedure != nil);
  996. if cap > 0 {
  997. __dynamic_array_reserve(array_, elem_size, elem_align, cap, loc);
  998. array.len = len;
  999. }
  1000. }
  1001. __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int, loc := #caller_location) -> bool {
  1002. array := (^Raw_Dynamic_Array)(array_);
  1003. // NOTE(tetra, 2020-01-26): We set the allocator before earlying-out below, because user code is usually written
  1004. // assuming that appending/reserving will set the allocator, if it is not already set.
  1005. if array.allocator.procedure == nil {
  1006. array.allocator = context.allocator;
  1007. }
  1008. assert(array.allocator.procedure != nil);
  1009. if cap <= array.cap do return true;
  1010. old_size := array.cap * elem_size;
  1011. new_size := cap * elem_size;
  1012. allocator := array.allocator;
  1013. new_data := allocator.procedure(allocator.data, .Resize, new_size, elem_align, array.data, old_size, 0, loc);
  1014. if new_data != nil || elem_size == 0 {
  1015. array.data = new_data;
  1016. array.cap = cap;
  1017. return true;
  1018. }
  1019. return false;
  1020. }
  1021. __dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int, loc := #caller_location) -> bool {
  1022. array := (^Raw_Dynamic_Array)(array_);
  1023. ok := __dynamic_array_reserve(array_, elem_size, elem_align, len, loc);
  1024. if ok do array.len = len;
  1025. return ok;
  1026. }
  1027. __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
  1028. items: rawptr, item_count: int, loc := #caller_location) -> int {
  1029. array := (^Raw_Dynamic_Array)(array_);
  1030. if items == nil do return 0;
  1031. if item_count <= 0 do return 0;
  1032. ok := true;
  1033. if array.cap <= array.len+item_count {
  1034. cap := 2 * array.cap + max(8, item_count);
  1035. ok = __dynamic_array_reserve(array, elem_size, elem_align, cap, loc);
  1036. }
  1037. // TODO(bill): Better error handling for failed reservation
  1038. if !ok do return array.len;
  1039. assert(array.data != nil);
  1040. data := uintptr(array.data) + uintptr(elem_size*array.len);
  1041. mem_copy(rawptr(data), items, elem_size * item_count);
  1042. array.len += item_count;
  1043. return array.len;
  1044. }
  1045. __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int, loc := #caller_location) -> int {
  1046. array := (^Raw_Dynamic_Array)(array_);
  1047. ok := true;
  1048. if array.cap <= array.len+1 {
  1049. cap := 2 * array.cap + max(8, 1);
  1050. ok = __dynamic_array_reserve(array, elem_size, elem_align, cap, loc);
  1051. }
  1052. // TODO(bill): Better error handling for failed reservation
  1053. if !ok do return array.len;
  1054. assert(array.data != nil);
  1055. data := uintptr(array.data) + uintptr(elem_size*array.len);
  1056. mem_zero(rawptr(data), elem_size);
  1057. array.len += 1;
  1058. return array.len;
  1059. }
  1060. // Map
  1061. __get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> Map_Header {
  1062. header := Map_Header{m = (^Raw_Map)(m)};
  1063. Entry :: struct {
  1064. key: Map_Key,
  1065. next: int,
  1066. value: V,
  1067. };
  1068. header.is_key_string = intrinsics.type_is_string(K);
  1069. header.entry_size = int(size_of(Entry));
  1070. header.entry_align = int(align_of(Entry));
  1071. header.value_offset = uintptr(offset_of(Entry, value));
  1072. header.value_size = int(size_of(V));
  1073. return header;
  1074. }
  1075. __get_map_key :: proc "contextless" (k: $K) -> Map_Key {
  1076. key := k;
  1077. map_key: Map_Key;
  1078. T :: intrinsics.type_core_type(K);
  1079. when intrinsics.type_is_integer(T) {
  1080. sz :: 8*size_of(T);
  1081. when sz == 8 do map_key.hash = u64(( ^u8)(&key)^);
  1082. else when sz == 16 do map_key.hash = u64((^u16)(&key)^);
  1083. else when sz == 32 do map_key.hash = u64((^u32)(&key)^);
  1084. else when sz == 64 do map_key.hash = u64((^u64)(&key)^);
  1085. else do #assert(false, "Unhandled integer size");
  1086. } else when intrinsics.type_is_rune(T) {
  1087. map_key.hash = u64((^rune)(&key)^);
  1088. } else when intrinsics.type_is_pointer(T) {
  1089. map_key.hash = u64(uintptr((^rawptr)(&key)^));
  1090. } else when intrinsics.type_is_float(T) {
  1091. sz :: 8*size_of(T);
  1092. when sz == 32 do map_key.hash = u64((^u32)(&key)^);
  1093. else when sz == 64 do map_key.hash = u64((^u64)(&key)^);
  1094. else do #assert(false, "Unhandled float size");
  1095. } else when intrinsics.type_is_string(T) {
  1096. #assert(T == string);
  1097. str := (^string)(&key)^;
  1098. map_key.hash = default_hash_string(str);
  1099. map_key.str = str;
  1100. } else {
  1101. #assert(false, "Unhandled map key type");
  1102. }
  1103. return map_key;
  1104. }
  1105. _fnv64a :: proc "contextless" (data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 {
  1106. h: u64 = seed;
  1107. for b in data {
  1108. h = (h ~ u64(b)) * 0x100000001b3;
  1109. }
  1110. return h;
  1111. }
  1112. default_hash :: proc "contextless" (data: []byte) -> u64 {
  1113. return _fnv64a(data);
  1114. }
  1115. default_hash_string :: proc "contextless" (s: string) -> u64 do return default_hash(transmute([]byte)(s));
  1116. source_code_location_hash :: proc(s: Source_Code_Location) -> u64 {
  1117. hash := _fnv64a(transmute([]byte)s.file_path);
  1118. hash = hash ~ (u64(s.line) * 0x100000001b3);
  1119. hash = hash ~ (u64(s.column) * 0x100000001b3);
  1120. return hash;
  1121. }
  1122. __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: Allocator, loc := #caller_location) -> bool {
  1123. array := (^Raw_Slice)(array_);
  1124. if new_count < array.len do return true;
  1125. assert(allocator.procedure != nil);
  1126. old_size := array.len*size_of(T);
  1127. new_size := new_count*size_of(T);
  1128. new_data := mem_resize(array.data, old_size, new_size, align_of(T), allocator, loc);
  1129. if new_data == nil do return false;
  1130. array.data = new_data;
  1131. array.len = new_count;
  1132. return true;
  1133. }
  1134. __dynamic_map_reserve :: proc(using header: Map_Header, cap: int, loc := #caller_location) {
  1135. __dynamic_array_reserve(&m.entries, entry_size, entry_align, cap, loc);
  1136. old_len := len(m.hashes);
  1137. __slice_resize(&m.hashes, cap, m.entries.allocator, loc);
  1138. for i in old_len..<len(m.hashes) do m.hashes[i] = -1;
  1139. }
  1140. __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int, loc := #caller_location) #no_bounds_check {
  1141. new_header: Map_Header = header;
  1142. nm := Raw_Map{};
  1143. nm.entries.allocator = m.entries.allocator;
  1144. new_header.m = &nm;
  1145. c := context;
  1146. if m.entries.allocator.procedure != nil {
  1147. c.allocator = m.entries.allocator;
  1148. }
  1149. context = c;
  1150. __dynamic_array_reserve(&nm.entries, entry_size, entry_align, m.entries.len, loc);
  1151. __slice_resize(&nm.hashes, new_count, m.entries.allocator, loc);
  1152. for i in 0 ..< new_count do nm.hashes[i] = -1;
  1153. for i in 0 ..< m.entries.len {
  1154. if len(nm.hashes) == 0 do __dynamic_map_grow(new_header, loc);
  1155. entry_header := __dynamic_map_get_entry(header, i);
  1156. data := uintptr(entry_header);
  1157. fr := __dynamic_map_find(new_header, entry_header.key);
  1158. j := __dynamic_map_add_entry(new_header, entry_header.key, loc);
  1159. if fr.entry_prev < 0 {
  1160. nm.hashes[fr.hash_index] = j;
  1161. } else {
  1162. e := __dynamic_map_get_entry(new_header, fr.entry_prev);
  1163. e.next = j;
  1164. }
  1165. e := __dynamic_map_get_entry(new_header, j);
  1166. e.next = fr.entry_index;
  1167. ndata := uintptr(e);
  1168. mem_copy(rawptr(ndata+value_offset), rawptr(data+value_offset), value_size);
  1169. if __dynamic_map_full(new_header) do __dynamic_map_grow(new_header, loc);
  1170. }
  1171. delete(m.hashes, m.entries.allocator, loc);
  1172. free(m.entries.data, m.entries.allocator, loc);
  1173. header.m^ = nm;
  1174. }
  1175. __dynamic_map_get :: proc(h: Map_Header, key: Map_Key) -> rawptr {
  1176. index := __dynamic_map_find(h, key).entry_index;
  1177. if index >= 0 {
  1178. data := uintptr(__dynamic_map_get_entry(h, index));
  1179. return rawptr(data + h.value_offset);
  1180. }
  1181. return nil;
  1182. }
  1183. __dynamic_map_set :: proc(h: Map_Header, key: Map_Key, value: rawptr, loc := #caller_location) #no_bounds_check {
  1184. index: int;
  1185. assert(value != nil);
  1186. if len(h.m.hashes) == 0 {
  1187. __dynamic_map_reserve(h, INITIAL_MAP_CAP, loc);
  1188. __dynamic_map_grow(h, loc);
  1189. }
  1190. fr := __dynamic_map_find(h, key);
  1191. if fr.entry_index >= 0 {
  1192. index = fr.entry_index;
  1193. } else {
  1194. index = __dynamic_map_add_entry(h, key, loc);
  1195. if fr.entry_prev >= 0 {
  1196. entry := __dynamic_map_get_entry(h, fr.entry_prev);
  1197. entry.next = index;
  1198. } else {
  1199. h.m.hashes[fr.hash_index] = index;
  1200. }
  1201. }
  1202. {
  1203. e := __dynamic_map_get_entry(h, index);
  1204. e.key = key;
  1205. val := (^byte)(uintptr(e) + h.value_offset);
  1206. mem_copy(val, value, h.value_size);
  1207. }
  1208. if __dynamic_map_full(h) {
  1209. __dynamic_map_grow(h, loc);
  1210. }
  1211. }
  1212. __dynamic_map_grow :: proc(using h: Map_Header, loc := #caller_location) {
  1213. // TODO(bill): Determine an efficient growing rate
  1214. new_count := max(4*m.entries.cap + 7, INITIAL_MAP_CAP);
  1215. __dynamic_map_rehash(h, new_count, loc);
  1216. }
  1217. __dynamic_map_full :: inline proc(using h: Map_Header) -> bool {
  1218. return int(0.75 * f64(len(m.hashes))) <= m.entries.cap;
  1219. }
  1220. __dynamic_map_hash_equal :: proc(h: Map_Header, a, b: Map_Key) -> bool {
  1221. if a.hash == b.hash {
  1222. if h.is_key_string do return a.str == b.str;
  1223. return true;
  1224. }
  1225. return false;
  1226. }
  1227. __dynamic_map_find :: proc(using h: Map_Header, key: Map_Key) -> Map_Find_Result #no_bounds_check {
  1228. fr := Map_Find_Result{-1, -1, -1};
  1229. if n := u64(len(m.hashes)); n > 0 {
  1230. fr.hash_index = int(key.hash % n);
  1231. fr.entry_index = m.hashes[fr.hash_index];
  1232. for fr.entry_index >= 0 {
  1233. entry := __dynamic_map_get_entry(h, fr.entry_index);
  1234. if __dynamic_map_hash_equal(h, entry.key, key) do return fr;
  1235. fr.entry_prev = fr.entry_index;
  1236. fr.entry_index = entry.next;
  1237. }
  1238. }
  1239. return fr;
  1240. }
  1241. __dynamic_map_add_entry :: proc(using h: Map_Header, key: Map_Key, loc := #caller_location) -> int {
  1242. prev := m.entries.len;
  1243. c := __dynamic_array_append_nothing(&m.entries, entry_size, entry_align, loc);
  1244. if c != prev {
  1245. end := __dynamic_map_get_entry(h, c-1);
  1246. end.key = key;
  1247. end.next = -1;
  1248. }
  1249. return prev;
  1250. }
  1251. __dynamic_map_delete_key :: proc(using h: Map_Header, key: Map_Key) {
  1252. fr := __dynamic_map_find(h, key);
  1253. if fr.entry_index >= 0 {
  1254. __dynamic_map_erase(h, fr);
  1255. }
  1256. }
  1257. __dynamic_map_get_entry :: proc(using h: Map_Header, index: int) -> ^Map_Entry_Header {
  1258. assert(0 <= index && index < m.entries.len);
  1259. return (^Map_Entry_Header)(uintptr(m.entries.data) + uintptr(index*entry_size));
  1260. }
  1261. __dynamic_map_erase :: proc(using h: Map_Header, fr: Map_Find_Result) #no_bounds_check {
  1262. if fr.entry_prev < 0 {
  1263. m.hashes[fr.hash_index] = __dynamic_map_get_entry(h, fr.entry_index).next;
  1264. } else {
  1265. prev := __dynamic_map_get_entry(h, fr.entry_prev);
  1266. curr := __dynamic_map_get_entry(h, fr.entry_index);
  1267. prev.next = curr.next;
  1268. }
  1269. if (fr.entry_index == m.entries.len-1) {
  1270. // NOTE(bill): No need to do anything else, just pop
  1271. } else {
  1272. old := __dynamic_map_get_entry(h, fr.entry_index);
  1273. end := __dynamic_map_get_entry(h, m.entries.len-1);
  1274. mem_copy(old, end, entry_size);
  1275. if last := __dynamic_map_find(h, old.key); last.entry_prev >= 0 {
  1276. last_entry := __dynamic_map_get_entry(h, last.entry_prev);
  1277. last_entry.next = fr.entry_index;
  1278. } else {
  1279. m.hashes[last.hash_index] = fr.entry_index;
  1280. }
  1281. }
  1282. // TODO(bill): Is this correct behaviour?
  1283. m.entries.len -= 1;
  1284. }