Date: Tue, 30 Oct 2007 17:14:38 +0000 From: "Poul-Henning Kamp" <phk@phk.freebsd.dk> To: Bakul Shah <bakul@bitblocks.com> Cc: Alfred Perlstein <alfred@freebsd.org>, Garance A Drosehn <gad@freebsd.org>, freebsd-arch@freebsd.org Subject: Re: C++ in the kernel Message-ID: <1821.1193764478@critter.freebsd.dk> In-Reply-To: Your message of "Tue, 30 Oct 2007 09:36:13 MST." <20071030163613.E70665B30@mail.bitblocks.com>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <20071030163613.E70665B30@mail.bitblocks.com>, Bakul Shah writes: >Is there a more detailed writeup of Poul's ideas on K >language beyond what is on the wiki.freebsd.org/K? Reading >it brings to mind Brinch Hansen's extensions to Pascal. Knowing that I may regret this, here is my private notes file on K syntax extensions. Preprocessor shell escape ------------------------- #! <command> { ident <stdin> } ident Generate C/K source with external program. Can be used to generate tables or include firmware files directly from the binary. Public/Private structs ---------------------- public struct foo { ... } Has sizeof() = -1, cannot be assigned. private struct foo { ... } Adds fields to the public struct foo, has sizeof the joint size. Acts like normal struct. Bitmaps ------- bitmap foo { bar, barf, ...}; Like enum, but assigns bit values and allows logical operations. Style/Syntax checks ------------------- Flag misindentation: if (some_cond) do_this(foo); and_that(bar); Style(9) warnings Macros taking code as argument ------------------------------ #define LOCK(a, {}) do { mtx_lock(&a); __CODE__ mtx_unlock(&a); } while (0); XXX: what happens on return/break/etc ? #define LOCK(a, {}) __CODE__( entry { mtx_lock(&a); } return { mtx_unlock(&a); } ) XXX: not happy about syntax Pointer colors -------------- void * "userland" ptr; Cannot be used as regular void *, but must be passed to functions which has same color prototype. Integer ranges -------------- int foo [21...45]; or int foo range [21...45]; Integer endianess ----------------- uint32_t big_endian foo; Atomic variables ---------------- uint32_t atomic foo; Struct offsets and sizes ------------------------ struct foo { sizeof 128; big_endian; align 16; uint8_t foo @0; uint32_t little_endian bar @12; } Multi-loop break ---------------- if (foo != NULL) { TAILQ_FOREACH(foo, &bar, list) { if (foo->idx == idx) break(2); } panic("not found"); } Call identification ------------------- int foo(int barf, void *there, private void **id); The "id" argument points to a call specific, globally unique, static instance of the pointed to type. This can be used for instance to cache a function pointer for lazy binding (KOBJ ?) Alternatively, even faster, go the full length and make run-time resolved function pointers (trouble hunting them down at modunload ?) Sensible jump prediction ------------------------ TAILQ_FOREACH(foo, &bar, list) {{ do_this_alot(foo); }} #include pointlessness warnings ------------------------------- Warn about #includes that have no effect Cross-Referencing ----------------- Generate cross-reference data on joint preproc/C/K level. Function instantiation by prototype ----------------------------------- typedef int foo_f(int arg, void *priv, struct *obj); static foo_f thisfunc(.) { if (arg) { ... } } Argument struct/array building ------------------------------ int foo(struct timeval tv); int bar(int someargs) { foo({.tv_sec = someargs}); } Compile time debugging aids --------------------------- * Look out for 0xdeadc0de+/-256 Check any pointer dereference against the indicated interval * Struct */void * typecheck Give each struct a magic identifier, check after void* transport. * Struct canary insertion Insert canary elements in struct and check their magic values whenever neighbouring elements are tweaked. * Assignment code insertion Insert code "foo" whenever variable "bar" is assigned or changed. Typical values of "foo" would be "mtx_assert_locked(...)" <sys/queue.h> replacement ------------------------- list_head(struct foo, ...) foolist; possible options: single Single linked list double Double linked list tail Tail is accessible from head head Head is accessible from elem member <name> Only allow use with member <name> in target struct. struct foo { list_member list; list_member(opts...) list2; }; list_empty(head) list_next(elem) list_prev(elem) list_first(head) list_last(head) list_insert_head(elem, head) list_insert_tail(elem, tail) list_insert_before(elem, elem {,head ?}) list_insert_after(elem, elem {,head ?}) list_remove(elem {,head ?}) list_init_head(head) list_take_first(head) list_take_last(head) list_foreach(elem, head {,member}) list_foreach_safe(elem, head {,member}) list_foreach_reverse(elem, head {,member}) list_foreach_reverse_safe(elem, head {,member}) -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk@FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1821.1193764478>