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