Comment: | major update. fix ridiculous old type size determination mechanism. mmap is still broken and i'm not sure why; the syscall does not appear to be going through correctly - see posix_mmap, kmheapa, and kcore/testbin.exe.fn |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
6479e060a3558bd8c304bd0018448ebc |
User & Date: | lexi on 2019-07-26 09:51:02 |
Other Links: | manifest | tags |
2019-07-26
| ||
10:52 | update kcore docs, fix bad type names and dumb logic check-in: 175dc46a91 user: lexi tags: trunk | |
09:51 | major update. fix ridiculous old type size determination mechanism. mmap is still broken and i'm not sure why; the syscall does not appear to be going through correctly - see posix_mmap, kmheapa, and kcore/testbin.exe.fn check-in: 6479e060a3 user: lexi tags: trunk | |
2019-06-29
| ||
09:31 | add a bunch of code, port the header mechanism to gpp; add a fuckton of definitions and compatibility header code; notably, add core function kstop and x86.lin.{32,64} impl. update docs accordingly check-in: e794c5edef user: lexi tags: trunk | |
Modified arch/makefile from [622e8ca4bc] to [3adea95421].
3 3 4 4 ${TMP}/calls.x86.lin.32.s: ${lin-headers}/unistd_32.h ${TMP} 5 5 grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@ 6 6 ${TMP}/calls.x86.lin.64.s: ${lin-headers}/unistd_64.h ${TMP} 7 7 grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@ 8 8 ${TMP}/calls.x86.fbsd.%.s: ${fbsd-headers}/syscall.h ${TMP} 9 9 grep "#define SYS_" $< | sed 's;^#define SYS_;%define sys.;' > $@ 10 +${TMP}/typesize: typesize.c 11 + $(CC) -std=c11 $< -o $@ 12 +${TMP}/typesize.def: ${TMP}/typesize 13 + $< > $@
Added arch/typesize.c version [9ee84449d7].
1 +#include <stdio.h> 2 +#include <limits.h> 3 +#include <stddef.h> 4 + 5 +#define sflag(flag,val) printf("-D"#flag"=\"%s\" ", val) 6 +#define mflag(flag,val) printf("-D"#flag"=-%llu ", val + 1) 7 +#define iflag(flag,val) printf("-D"#flag"=%llu ", val) 8 +#define fflag(flag,val) printf("-D"#flag"=%Lf ", val) 9 +#define type_found(val) (found_type & (val / 8)) 10 +#define checkbits(type,x) \ 11 + if(!type_found(x) && sizeof(type) == (x/CHAR_BIT)) \ 12 + sflag(type_bit##x, #type), found_type |= (x / 8) 13 + 14 +#define describe_integral(type,label) { \ 15 + unsigned type maxval = -1; \ 16 + unsigned type smaxval = (maxval/2) - 1; \ 17 + iflag(type_max_u_##label, maxval); \ 18 + iflag(type_max_s_##label, smaxval); \ 19 + mflag(type_min_s_##label, smaxval); \ 20 + iflag(type_##label##_bits, (CHAR_BIT * sizeof(type))); \ 21 + checkbits(type, 8); else checkbits(type,16); else \ 22 + checkbits(type,32); else checkbits(type,64); else \ 23 + checkbits(type,128); else \ 24 + if (!found_sz && sizeof(type) == sizeof(size_t)) \ 25 + found_sz = 1, sflag(type_sz, "unsigned " #type); \ 26 + if (!found_ofs && sizeof(type) == sizeof(ptrdiff_t)) \ 27 + found_ofs = 1, sflag(type_offset, "signed " #type); \ 28 +} 29 + 30 +int main() { 31 + int found_sz = 0, found_ofs = 0, found_type = 0; 32 + iflag(byte_bits,CHAR_BIT); 33 + describe_integral(char,char); 34 + describe_integral(short,short); 35 + describe_integral(int,int); 36 + describe_integral(long,long); 37 + describe_integral(long long,llong); 38 + printf("\n"); 39 + return 0; 40 +}
Added kconf/kconf.md version [b260f2842a].
1 +# kconf 2 + 3 +while there are a number of existing configuration parser libraries out there, they all have their problems, and all depend on libc. since configuration string parsing is a fairly core functionality that would force many programs to either write their own code or drag libc back into their dependencies, supplying a basic parser with libk makes sense. 4 + 5 +## basic principles 6 + 7 +kconf is intended to be fast, lightweight, transparent, and low-overhead. 8 + 9 +to initialize a kconf structure, we begin by supplying a list of *atoms.* like in Xlib, an atom is a performant way to reference a known string of text from a compiled program. we can do this in two different ways, either by generating the values ourselves at compile time with an enum, or by generating them at runtime using the appropriate kconf interface. note that if you supply your own with an enum, because zero is used for in-band error signalling, the first atom should always be an error token. alternately, it may be explicitly set to a non-zero number and a return value of zero can be checked for implicitly or against a literal 0. 10 + 11 +note that, in a recurring libk pattern, if an element count of zero (or `null`) is passed to a function that takes an array of nullables, that function will treat its array argument as a null-terminated array to be counted at runtime. 12 + 13 +kconf is initialized by filling out the struct `kconf` with the parameters of operations and then passing it to the appropriate function. 14 + 15 + enum atoms { parse_error, user, pw, email, atomct }; 16 + kconf kc = { 17 + .decl = { atomct, { 18 + { user, {4, "user" } }, 19 + { pw, {8, "password"} }, 20 + { email, {5, "email" } } 21 + }} 22 + }; 23 + 24 + /* with runtime counts: 25 + * enum atoms { parse_error, user, pw, email }; 26 + * kconf kc = { 27 + * .decl = { null, { 28 + * { user, {0, "user" } }, 29 + * { pw, {0, "password"} }, 30 + * { email, {0, "email" } }, 31 + * { null } 32 + * }} 33 + * }; */ 34 + 35 + /* with macros: 36 + * enum atoms { parse_error, user, password, email }; 37 + * kconf kc = { 38 + * .decl = {Kmpsa(kconf_decl, { 39 + * Kconf_atom(user), 40 + * Kconf_atom(password), 41 + * Kconf_atom(email) 42 + * })}; 43 + * }; */ 44 + 45 +## types 46 + 47 +### struct kconf 48 + * `union { kconf_decl decl; kconf_gen gen; };` 49 + 50 +### struct kconf_atom 51 + 52 + * `sz key` 53 + * `ksraw string` 54 + 55 +### struct kconf_pair 56 + 57 + * `kconf_atom atom` 58 + * `ksraw* dest` 59 + 60 + 61 +## macros 62 + 63 + * `Kconf_atom(atom)` - a convenience macro for definining an pre-defined atom structure (`kconf_atom`), under the assumption that the C enumerator name is the same as the string used to name the field in the configuration file. inserts the text `{atom, {sizeof(#atom), #atom}}` 64 + * `Kconf_atom_pfx(pfx,atom)` - a convenience macro for definining an pre-defined atom structure (`kconf_atom`), under the assumption that the C enumerator name is the string used to name the field in the configuration file with a prefix attached. inserts the text `{pfx##atom, {sizeof(#atom), #atom}}`
Added kconf/makefile version [f0df06fe05].
1 +include ../modmake
Modified kcore/core.h from [ded1289884] to [46cfa15699].
85 85 # define KVstd c++ 86 86 # if (__cplusplus >= 201103L) 87 87 # define KFstd_cpp11 88 88 # define KVstd c++11 89 89 # endif /* TODO: add more */ 90 90 # endif 91 91 #endif 92 + 93 +#ifdef KFstd_c11 94 +# define Kassert _Static_assert 95 +#else 96 +# define Kassert(x) { struct { int assertion_failed[(x) ? 1 : -1] }; } 97 +#endif 92 98 93 99 /* hooo boy. null. that one's got a storied 94 100 * history across the versions and dialects. 95 101 * below, we try to find the ideal way to 96 102 * offer a "null" "keyword" depending on 97 103 * dialect, version, and whether the user 98 104 * has asked for macros to be suspended. ................................................................................ 117 123 # define noreturn [[ noreturn ]] 118 124 #elif __STDC_VERSION__ >= 201103L 119 125 # define noreturn _Noreturn 120 126 #else 121 127 # define noreturn 122 128 #endif 123 129 124 -noreturn void kstop(longstat code); 130 +noreturn void kstop(stat_long code); 125 131 126 132 #ifdef KFclean 127 133 # undef noreturn 128 134 #endif 129 135 130 136 #endif
Modified kcore/def.h.m from [9abe158651] to [9c53671363].
1 1 --- kcore/def.h.m → <k/def.h> 2 2 --- ~ lexi hale <lexi@hale.su> 3 3 --- this file gathers information on the environment it's 4 4 --- being compiled in, setting macros that other headers 5 5 --- need. it will be emitted as <k/def.h>. 6 6 --- vim: ft=c 7 +#ifndef KIdef 8 +#define KIdef 7 9 8 10 [ifdef atom_target_bits] 9 11 [define target: [atom_target_arch].[atom_target_os].[atom_target_bits]] 10 12 #define KVbits [atom_target_bits] 11 13 [else] 12 14 [define target: [atom_target_arch].[atom_target_os]] 13 15 [endif] ................................................................................ 26 28 #define Kpragma(p) _Pragma(#p) 27 29 #if defined(__GNUC__) || defined(__clang__) 28 30 # define Kerror(msg) Kpragma(GCC error #msg) 29 31 #else 30 32 # define Kerror(msg) Kpragma(message #msg) 31 33 #endif 32 34 #define Knoimpl(fn) Kerror(no implementation of fn for platform [target]) 35 + 36 +#endif
Modified kcore/magic.h from [1f7f63c3e2] to [a7232aabca].
2 2 * ~ lexi hale <lexi@hale.su> 3 3 * one of libk's biggest goals is standardization across 4 4 * software. for this reason, we define here a variety 5 5 * of "magical numbers" used to signal or describe 6 6 * various states, messages, and errors. suggestions are 7 7 * welcome. 8 8 */ 9 +#ifndef KImagic 10 +#define KImagic 11 + 9 12 #include <k/type.h> 10 13 11 14 typedef enum kbad { 12 15 // values to be returned by an entry function 13 16 kbad_ok = 0, 14 17 /* the requested operation completed 15 18 * successfully */ 16 19 20 + kbad_mem = 1, 21 + /* the system does not have enough free 22 + * memory to complete the requested operation */ 23 + 17 24 /* these are synchronized with freebsd's existing 18 25 * sysexit.h conventions. */ 19 26 kbad_usage = 64, 20 27 /* # fbsd EX_USAGE 21 28 * a usage screen was displayed to the user 22 29 * on request or due to improperly formed call */ 23 30 kbad_data = 65, ................................................................................ 61 68 /* # fbsd EX_NOPERM 62 69 * you or the program do not have permissions 63 70 * to do the thing requested */ 64 71 kbad_conf = 78, 65 72 /* # fbsd EX_CONFIG 66 73 * your configuration is fucked */ 67 74 } kbad; 75 + 76 +#endif
Modified kcore/makefile from [c01fcd380e] to [f9fefae3d1].
3 3 # for stddef.h, and that can't be written in portable C. 4 4 # so we're generating it at build time. 5 5 6 6 # gen-headers = type.h 7 7 8 8 include ../modmake 9 9 10 +${OUT}/k/type.h: type.h.m ${TMP}/typesize.def 11 + $(m-comp) $< $(file < ${TMP}/typesize.def) > $@ 12 + 10 13 ## the below code predates the introduction of gpp 11 14 ## to generate these headers from templates instead 12 15 ## of trying to write one for everypossible arch 13 16 ## tuple. it is left as a monument to a terrible 14 17 ## and now blissfully forgotten past. 15 18 # 16 19 # look, imma just be straight with you. the mechanism we're
Modified kcore/stop.fn.c from [c4373dead4] to [5c15d4cc49].
5 5 6 6 #include <k/core.h> 7 7 #include <k/def.h> // so we know what system this is 8 8 #include <k/type.h> 9 9 10 10 #ifdef KFenv_posix 11 11 # define STOPFN kio_posix_exit 12 - extern void STOPFN(int); 12 + extern noreturn void STOPFN(int); 13 13 #else 14 14 Knoimpl(kstop) 15 15 #endif 16 16 17 -noreturn void kstop (longstat code) { STOPFN(code); } 17 +noreturn void kstop (stat_long code) { STOPFN(code); }
Modified kcore/testbin.exe.c from [f1bdb07ea2] to [5796abefa5].
1 1 #include <k/core.h> 2 2 #include <k/mem.h> 3 3 #include <k/io.h> 4 4 #include <k/magic.h> 5 + 6 +struct object { 7 + u8 a; 8 + s16 b; 9 + bool c; 10 +}; 5 11 6 12 kbad entry(kenv e) { 7 13 const char msg[] = "hello from libk\n"; 8 14 ksraw ptr = { Kmsz(msg), msg }; 9 15 10 16 bool maybe = true; 11 17 maybe = no; 12 18 13 19 if (kiosend(e.std, ptr, null) == kiocond_ok) { 14 - return kbad_ok; 20 + /* great, continue */ 15 21 } else { 16 22 return kbad_io; 17 23 } 24 + 25 + struct object* block = kmheapa(sizeof (struct object) * 4); 26 + if (block == null) return kbad_mem; else return kbad_ok; 27 + 28 + block[1].a = 5; 29 + 30 + return kbad_ok; 18 31 }
Modified kcore/type.h.m from [8b1f2e0cb2] to [a9978dfd3a].
1 ---- kcore/type.h.m → <k/def.h> 1 +--- kcore/type.h.m → <k/type.h> 2 2 --- ~ lexi hale <lexi@hale.su> 3 3 --- this file gathers information on the environment it's 4 4 --- being compiled in, defining types that our code 5 5 --- needs. it will be emitted as <k/type.h>. 6 6 --- vim: ft=c 7 +#ifndef KItype 8 +#define KItype 9 + 10 +typedef unsigned char kc_uint_min; 11 +typedef signed char kc_sint_min; 12 +typedef unsigned long long kc_uint_max; 13 +typedef signed long long kc_sint_max; 14 + 15 +[ifdef type_bit8] 16 + typedef unsigned [type_bit8] u8; 17 + typedef signed [type_bit8] s8; 18 +[else] 19 + typedef kc_uint_min u8; 20 + typedef kc_sint_min s8; 21 +[endif] 22 + 23 +[ifdef type_bit16] 24 + typedef unsigned [type_bit16] u16; 25 + typedef signed [type_bit16] s16; 26 +[else] 27 + typedef kc_uint_max u16; 28 + typedef kc_sint_max s16; 29 +[endif] 30 + 31 +[ifdef type_bit32] 32 + typedef unsigned [type_bit32] u32; 33 + typedef signed [type_bit32] s32; 34 +[else] 35 + typedef kc_uint_max u32; 36 + typedef kc_sint_max s32; 37 +[endif] 38 + 39 +[ifdef type_bit64] 40 + typedef unsigned [type_bit64] u64; 41 + typedef signed [type_bit64] s64; 42 + [ifndef type_bit128] 43 +# if defined(__GNUC__) || defined(__clang__) 44 + typedef unsigned __int128_t u128; 45 + typedef signed __int128_t s128; 46 +# else 47 + typedef kc_uint_max u128; 48 + typedef kc_sint_max s128; 49 +# endif 50 + [endif] 51 +[else] 52 + typedef kc_uint_max u64; 53 + typedef kc_sint_max s64; 54 + 55 + typedef kc_uint_max u128; 56 + typedef kc_sint_max s128; 57 +[endif] 58 + 59 +[ifdef type_bit128] 60 + typedef unsigned [type_bit128] u128; 61 + typedef signed [type_bit128] s128; 62 +[endif] 63 + 64 +enum /* max-min values of each type */ { 65 + /* assuming two's complement. TODO: check math */ 66 + /* TODO: figure out how to calc min */ 67 + kc_byte_bits = [byte_bits], 68 + u8_min = 0, u8_max = ((u8)-1), 69 + u16_min = 0, u16_max = ((u16)-1), 70 + u32_min = 0, u32_max = ((u32)-1), 71 + u64_min = 0, u32_max = ((u64)-1), 72 + u128_min = 0, u128_max = ((u128)-1), 73 + 74 + [define merge: $1$2] 75 + [define [sspec type]: 76 + [merge [type],_min] = 0 - ((1 << sizeof([type]) * kc_byte_bits) / 2), 77 + [merge [type],_max] = (1 << sizeof([type]) * kc_byte_bits) / 2 - 1] 78 + 79 + [sspec s8], [sspec s16], [sspec s32], 80 + [sspec s64], [sspec s128], 81 + 82 + kc_min_uchar = 0, kc_max_uchar = [type_max_u_char], 83 + kc_min_ushort = 0, kc_max_ushort = [type_max_u_short], 84 + kc_min_uint = 0, kc_max_uint = [type_max_u_int], 85 + kc_min_ulong = 0, kc_max_ulong = [type_max_u_long], 86 + kc_min_ullong = 0, kc_max_ullong = [type_max_u_llong], 87 + 88 + kc_min_schar = [type_min_s_char], kc_max_schar = [type_max_s_char], 89 + kc_min_sshort = [type_min_s_short], kc_max_sshort = [type_max_s_short], 90 + kc_min_sint = [type_min_s_int], kc_max_sint = [type_max_s_int], 91 + kc_min_slong = [type_min_s_long], kc_max_slong = [type_max_s_long], 92 + kc_min_sllong = [type_min_s_llong], kc_max_sllong = [type_max_s_llong], 93 +}; 7 94 8 -// arch bit length [atom_target_bits] 9 ---- make some gigantic fucking assumptions 10 -[if [atom_target_bits] >= 8] 11 - typedef unsigned char u8; 12 - typedef signed char s8; 13 - [if [atom_target_bits] >= 16] 14 - typedef unsigned short u16; 15 - typedef signed short s16; 16 - [if [atom_target_bits] >= 32] 17 - typedef unsigned long u32; 18 - typedef signed long s32; 19 - [if [atom_target_bits] >= 64] 20 - typedef unsigned long long u64; 21 - typedef signed long long s64; 22 - [if [atom_target_arch] == x86] 23 - #if defined(__GNUC__) || defined(__clang__) 24 - typedef __uint128_t u128; 25 - typedef __int128_t s128; 26 - #endif 27 - [endif] 28 - [endif] 29 - [endif] 30 - [endif] 95 +[ifdef type_sz] 96 + typedef [type_sz] sz; 97 +[else] 98 +# ifdef __cplusplus 99 + /* C++ gives us a clean, standardized way to do this */ 100 + typedef decltype (sizeof(char)) sz; 101 +# else 102 +# if defined(__GNUC__) || defined(__clang__) 103 + typedef __typeof__ (sizeof(char)) sz; 104 +# else 105 + /* we're stumped - set sz to the safest possible value under 106 + * the circumstances, and warn the user. */ 107 +# warning no authoritative sz (size_t) type definition \ 108 + available; defaulting to largest unsigned integer type 109 + typedef kc_uint_max sz; 110 +# endif 111 +# endif 31 112 [endif] 32 113 33 -typedef u[atom_target_bits] sz; 34 -typedef s[atom_target_bits] ssz; 35 - 36 ---- make sure something unlikely doesn't happen 37 -[define [maxtype name, n]: 38 - [if [n] > [atom_target_bits]] 39 - typedef u[atom_target_bits] [name] 40 - [else] 41 - typedef u[n] [name] 42 - [endif]] 114 +[ifdef type_offset] 115 + typedef [type_offset] offset; 116 +[else] 117 +# ifdef __cplusplus 118 + /* C++ gives us a clean, standardized way to do this */ 119 + typedef decltype (((void*)-1) - 1) offset; 120 +# else 121 +# if defined(__GNUC__) || defined(__clang__) 122 + typedef __typeof__ (((void*)10) - ((void*)5)) offset; 123 +# else 124 + /* no dice - set offset to the safest possible value under 125 + * the circumstances, and warn the user. */ 126 +# warning no authoritative offset (ptrdiff_t) type definition \ 127 + available; defaulting to largest unsigned integer type 128 + typedef kc_sint_max offset; 129 +# endif 130 +# endif 131 +[endif] 43 132 44 133 // exit status integer types - pls use kbad in <k/magic.h> instead 45 134 [if [target_posix] == yes] 46 135 /* by convention, posix return values are 8-bit, 47 136 * but note that many modern UNIXes do technically 48 137 * support higher-bit values. for this reason, 49 138 * longstat is defined differently under posix. */ 50 139 typedef u8 stat; 51 - [maxtype longstat, 32]; 140 + typedef u32 stat_long; 52 141 [else] 53 142 [if ([atom_target_os] == win) || 54 143 ([atom_target_os] == vms)] 55 - [maxtype stat, 32] 144 + typedef u32 stat; 56 145 [else] 57 146 typedef u8 stat; 58 147 /* we don't know a specific exit status type 59 148 * for your arch so we're going with a sane 60 149 * default. if this is wrong, help us fix it! */ 61 150 [endif] 62 - typedef stat longstat; 151 + typedef stat stat_long; 63 152 [endif] 153 + 154 +#endif
Added kdb/kdb.md version [1c2867c8a9].
1 +# kdb 2 + 3 +kdb is a module for storing and loading data from files. 4 + 5 +## model 6 + 7 +the first argument to all kdb functions is of type `struct kdb`, which describes the database to be accessed. the first field of that struct is a pointer to a struct of type `struct kdb_fmt` which describes the format of the database. 8 + 9 +kdb encodes records as a tuple of three fields: (kind, key, value). `kind` is a 16-bit integer, `key` is an integer of platform width, and `value` is a blob decoded according to the type of the record, which is not saved in the database itself. records are indexed by the tuple (kind, key); `key` may be null. `kind` denotes the structure of the record, and is user-defined. 10 + 11 +to use strings as the keys for database entries, either atoms should be stored in the database or a hash function may be used. kdb contains procedures to automate the use of atoms as keys. 12 + 13 +## types 14 + 15 +### struct kdb 16 + 17 + * `struct kdb_fmt* fmt` 18 + * `enum kdb_conn conn` 19 + * `union { kfile* file; const kdb_store* mem; kmptr ptr; } store;` 20 + 21 +### struct kdb_rec 22 + 23 + * `u16 kind` 24 + * `word key` 25 + * `ksraw value` 26 + 27 +### enum kdb_conn 28 + 29 + * `kdb_conn_none`: no database is connected; calls will fail 30 + * `kdb_conn_file`: the database is stored in a file; calls to modify it will modify the file on-disk 31 + * `kdb_conn_file_static`: the database is stored in a file; calls to modify it will fail. if the file is writable to the process, can be seamlessly changed to `kdb_conn_file` and vice-versa 32 + * `kdb_conn_mem`: the database is stored in-memory, allocated by kmem and referenced by `ptr`. calls to modify it will re-allocate memory via the appropriate interfaces. 33 + * `kdb_conn_mem_static`: the database is stored in-memory, referenced by `mem`; calls to modify it will fail 34 +
Added kdb/makefile version [f0df06fe05].
1 +include ../modmake
Modified kio/io.h from [aa4095c969] to [e3d3c3c357].
39 39 kiostream in; 40 40 // text can be read from this stream 41 41 kiostream out; 42 42 // text can be written to this stream 43 43 } kiochan; 44 44 45 45 typedef enum kiocond { 46 - kiocond_ok, 47 - // success 48 - kiocond_fail, 49 - // action failed 46 + /* to check if a call failed, perform (x >= kiocond_fail) where x 47 + * is that call's return value. more typically however you should 48 + * select explicitly against kiocond_ok or kiocond_partial, since 49 + * those situations will usually need to be handled differently. */ 50 + 51 + kiocond_ok, // success 52 + kiocond_partial, // partial read or write 53 + 54 + kiocond_fail, // action failed - unspecified reason 55 + kiocond_fail_closed_stream, // action failed because stream is closed 50 56 } kiocond; 51 57 52 58 kiocond kiosend(kiochan, ksraw, sz*); // send data to a channel 53 59 kiocond kiorecv(kiochan, ksraw*); // receive data from a channel 54 60 kmptr kiorecvall(kiochan, kmcell*, kmkind); // automatically allocate a bufer for a channel 55 61 // kmkind is only used if kmcell* is NULL 56 62 kiocond kiocon(kiochan, kiochan); // connect one channel to another 57 63 58 64 #endif
Deleted kio/kio_posix_fd_write.fn.x86.lin.32.s version [7b77d86bab].
1 -bits 32 2 -global kio_posix_fd_write 3 - 4 -%include "../arch/x86.lin.32.s" 5 -; vim: ft=nasm 6 - 7 -kio_posix_fd_write: 8 - mov sys.reg.0, sys.call.write 9 - mov sys.reg.1, [esp + 4] ; holy god but this took the most 10 - mov sys.reg.2, [esp + 8] ; stupidly long time to fucking 11 - mov sys.reg.3, [esp + 12]; figure out 12 - sys.call 13 - ret 14 -
Deleted kio/kio_posix_fd_write.fn.x86.lin.64.s version [b72b3eff18].
1 -bits 64 2 -global kio_posix_fd_write 3 - 4 -%include "../arch/x86.lin.64.s" 5 -; vim: ft=nasm 6 - 7 -kio_posix_fd_write: 8 - mov sys.reg.0, sys.write 9 - ; mov sys.reg.1, ccall.reg.0 - nop 10 - ; mov sys.reg.2, ccall.reg.1 - nop 11 - ; mov sys.reg.3, ccall.reg.2 - nop 12 - sys.call 13 - ret 14 -
Added kio/posix_fd_write.fn.x86.lin.32.s version [7b77d86bab].
1 +bits 32 2 +global kio_posix_fd_write 3 + 4 +%include "../arch/x86.lin.32.s" 5 +; vim: ft=nasm 6 + 7 +kio_posix_fd_write: 8 + mov sys.reg.0, sys.call.write 9 + mov sys.reg.1, [esp + 4] ; holy god but this took the most 10 + mov sys.reg.2, [esp + 8] ; stupidly long time to fucking 11 + mov sys.reg.3, [esp + 12]; figure out 12 + sys.call 13 + ret 14 +
Added kio/posix_fd_write.fn.x86.lin.64.s version [b72b3eff18].
1 +bits 64 2 +global kio_posix_fd_write 3 + 4 +%include "../arch/x86.lin.64.s" 5 +; vim: ft=nasm 6 + 7 +kio_posix_fd_write: 8 + mov sys.reg.0, sys.write 9 + ; mov sys.reg.1, ccall.reg.0 - nop 10 + ; mov sys.reg.2, ccall.reg.1 - nop 11 + ; mov sys.reg.3, ccall.reg.2 - nop 12 + sys.call 13 + ret 14 +
Deleted kio/send.c version [d88d1642fe].
1 -#include <k/io.h> 2 -#include <k/core.h> 3 -#include <k/def.h> 4 -/* send.c - kiosend() 5 - * ~ lexi hale <lexi@hale.su> 6 - * kiosend() writes to a channel with an open out stream 7 - */ 8 - 9 -// we define all platform functions here, 10 -// whether or not they're for the correct 11 -// platform - only the ones actually called 12 -// by the generated code will be linked 13 -extern sz kio_posix_fd_write(int fd, const char* buf, sz len); 14 - 15 -kiocond kiosend(kiochan target, ksraw string, sz* len) { 16 -# ifdef KFenv_posix 17 - sz size = kio_posix_fd_write(target.out.platform_fd, string.ptr, string.size); 18 - if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors 19 -# else 20 -# if KVos == win 21 -# error windows IO send function not yet defined 22 -# else 23 - Knoimpl(kiosend,KVos); 24 -# error missing implementation // boring error for plebs 25 -# endif 26 -# endif 27 - 28 - if (len != null) *len = size; 29 - return kiocond_ok; 30 -}
Modified kio/send.fn.c from [430158e543] to [5cc5cc2649].
1 1 #include <k/io.h> 2 2 #include <k/core.h> 3 3 #include <k/def.h> 4 -/* send.c - kiosend() 4 +/* send.c - kiosend() "send to channel" 5 5 * ~ lexi hale <lexi@hale.su> 6 6 * kiosend() writes to a channel with an open out stream 7 7 */ 8 8 9 -// we define all platform functions here, 10 -// whether or not they're for the correct 11 -// platform - only the ones actually called 12 -// by the generated code will be linked 9 +/* we define all platform functions here, 10 + * whether or not they're for the correct 11 + * platform - only the ones actually called 12 + * by the generated code will be linked */ 13 13 extern sz kio_posix_fd_write(int fd, const char* buf, sz len); 14 14 15 15 kiocond kiosend(kiochan target, ksraw string, sz* len) { 16 + if (target.out.kind == kiostream_closed) return kiocond_fail_closed_stream; 17 + 16 18 # ifdef KFenv_posix 17 19 sz size = kio_posix_fd_write(target.out.platform_fd, string.ptr, string.size); 18 20 if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors 19 21 # else 20 22 # if KVos == win 21 23 # error windows IO send function not yet defined 22 24 # else 23 - _Pragma("GCC diagnostic error \"" // fancy error for gcc 24 - "IO send fn for platform " #KVos " not defined" 25 - "\"")) 26 -# error IO send fn not defined for platform 27 - // boring error for plebs 25 + Knoimpl(kiosend,KVos); 26 +# error missing implementation // boring error for plebs 28 27 # endif 29 28 # endif 30 29 31 30 if (len != null) *len = size; 32 31 return kiocond_ok; 33 32 }
Added kmem/heapa.fn.c version [f32eb209ee].
1 +#include <k/core.h> 2 +#include <k/def.h> 3 +/* heapa.c - kmheapa() "heap alloc" 4 + * ~ lexi hale <lexi@hale.su> 5 + * kmheapa() allocates a pointer on the heap à la libc malloc() 6 + * see also: kmheapf() "heap free" 7 + */ 8 + 9 +/* we define all platform functions here, 10 + * whether or not they're for the correct 11 + * platform - only the ones actually called 12 + * by the generated code will be linked, 13 + * linker errors are our friend here! */ 14 +extern void* kmem_posix_mmap(void* addr, 15 + unsigned long sz, unsigned long prot, unsigned long flags, 16 + unsigned long fd, unsigned long off); 17 + 18 +enum posix_prot { 19 + posix_prot_none = 0, 20 + posix_prot_read = 1 << 0, 21 + posix_prot_write = 1 << 1, 22 + posix_prot_exec = 1 << 2 23 +}; 24 + 25 +enum posix_map { 26 + posix_map_shared = 1, 27 + posix_map_private = 2 28 +}; 29 + 30 +enum posix_flag { 31 + posix_flag_fixed = 0x10, 32 + posix_flag_anonymous = 0x20, 33 + 34 + /* platform flags */ 35 + posix_flag_linux_hugetlb = 0x40000 36 +}; 37 + 38 +void* kmheapa(sz len) { 39 + /* allocate an object on the heap and return 40 + * a pointer, or NULL if the allocation failed. */ 41 + void* val; 42 + 43 +# ifdef KFenv_posix 44 + /* posix APIs - we've got it easy */ 45 + val = kmem_posix_mmap(null, len, posix_prot_read | posix_prot_write, 46 + posix_flag_anonymous, -1, 0); 47 + /* impl note: while per manpage fd is "ignored" 48 + * for MAP_ANONYMOUS, "some implementations" require 49 + * a value of -1 */ 50 + 51 + if (val == (void*) -1) return null; 52 + /* worth retrieving errno? discuss */ 53 + 54 +# else 55 + Knoimpl(kmheapa,KVos); 56 +# error missing implementation 57 +# endif 58 + 59 + return val; 60 +}
Modified kmem/kmem.md from [9ed4178122] to [18509d6a57].
155 155 * `kmtreef(void*) → kmptr` - frees a node and all its children 156 156 157 157 ## macros 158 158 159 159 kmem defines the following macros. 160 160 161 161 * `Kmsz(array)` - a convenience macro to return the number of elements in a static array. inserts the text `( sizeof (array) / sizeof (array) [0] )` 162 + * `Kmszs(type, struct)` - a convenience macro to return the size of a struct. requires compound literals. 163 + * `Kmszsa(type, array)` - calculates the number of elements in an array of a given struct type. inserts the text `( sizeof ( (type) array ) / sizeof (type) )` 164 + * `Kmpsa(type, struct)` - a convenience macro to insert a "pascal struct array" - that is, a struct array prefixed with a size value. this is equivalent to `Kmszsa(type, array), array`
Modified kmem/mem.h from [551899b415] to [ace4d63e01].
31 31 typedef struct kmptr { 32 32 kmkind kind; 33 33 kmshred shred; 34 34 void* ref; 35 35 kmcell* cell; 36 36 } kmptr; 37 37 38 +/* heap functions */ 39 + 40 +void* kmheapa(sz); 41 +void kmheapf(void*); 42 + 38 43 #endif
Added kmem/posix_mmap.fn.x86.lin.64.s version [0ee1179d8c].
1 +bits 64 2 +%include "../arch/x86.lin.64.s" 3 +%include "../arch/x86.cdecl.64.s" 4 +; vim: ft=nasm 5 + 6 +global kmem_posix_mmap 7 +kmem_posix_mmap: 8 + ; to call mmap, we need to translate the cdecl64 9 + ; register arguments to their appropriate syscall64 10 + ; registers. these are mostly the same, with one 11 + ; obnoxious exception. the NOPs have been written 12 + ; in as comments to aid in understanding. 13 + 14 + mov sys.reg.1, ccall.reg.0 ;nop - rdi → rdi 15 + mov sys.reg.2, ccall.reg.1 ;nop - rsi → rsi 16 + mov sys.reg.3, ccall.reg.2 ;nop - rdx → rdx 17 + mov sys.reg.4, ccall.reg.3 ; OP - rcx → r10 18 + mov sys.reg.5, ccall.reg.4 ;nop - r8 → r8 19 + mov sys.reg.6, ccall.reg.5 ;nop - r9 → r9 20 + 21 + mov sys.reg.0, sys.mmap 22 + sys.call 23 + 24 + mov ccall.reg.ret, sys.reg.ret ; rax → rdi
Modified kstr/str.h from [f7e947c0d1] to [69d05c5e37].
6 6 typedef struct kstr { 7 7 sz size; 8 8 kmptr ptr; 9 9 } kstr; 10 10 11 11 typedef struct ksraw { 12 12 sz size; 13 - char* ptr; 13 + const char* ptr; 14 14 } ksraw; 15 + 16 +typedef struct ksmut { 17 + sz size; 18 + char* ptr; 19 +} ksmut; 15 20 #endif
Modified makefile from [d63468c69f] to [ce9c7792cb].
100 100 101 101 %.tool: %/makefile $(TMP)/precomp.g $(OUT) 102 102 cd $* && $(MAKE) tool 103 103 104 104 %.dbg: %/makefile $(OUT) 105 105 cd $* && $(MAKE) dbg 106 106 107 -%.def: %/makefile $(TMP)/precomp.g $(OUT) $(OUT)/k 107 +%.def: %/makefile $(TMP)/precomp.g $(TMP)/typesize.def $(OUT) $(OUT)/k 108 108 cd $* && $(MAKE) def 109 109 110 110 %.calls: arch/makefile 111 111 cd arch && $(MAKE) $(TMP)/calls.$*.s 112 112 113 113 $(TMP)/precomp.g: grammar/precomp.g.gpp $(TMP) 114 114 cd grammar && $(MAKE) $@ 115 + 116 +$(TMP)/typesize.def: arch/makefile $(TMP) 117 + cd arch && $(MAKE) $@ 115 118 116 119 $(OUT)/libk.so: $(fnobjects) 117 120 ld -shared $(COMPLIB) -o $@ $^ 118 121 @# $(CC) -shared -fPIC -nostdlib $(COMPLIB) -o $@ $(OUT)/*.o 119 122 120 123 $(OUT)/boot.o: $(rtobjects) 121 124 ld -r $^ -o $(OUT)/boot.o