rt: move slice append helpers from lib/slices/ into libwwrt.a
This commit is contained in:
11
Makefile
11
Makefile
@@ -39,7 +39,8 @@ W6L_SRC = cmd/w6l/main.c cmd/w6l/obj.c cmd/w6l/sym.c cmd/w6l/pass.c cmd/w6l/out.
|
|||||||
W6L_OBJ = $(W6L_SRC:cmd/w6l/%.c=$(OBJ)/w6l/%.o)
|
W6L_OBJ = $(W6L_SRC:cmd/w6l/%.c=$(OBJ)/w6l/%.o)
|
||||||
|
|
||||||
RT_S = rt/start.s rt/syscall.s rt/alloc.s rt/streq.s rt/abort.s
|
RT_S = rt/start.s rt/syscall.s rt/alloc.s rt/streq.s rt/abort.s
|
||||||
RT_OBJ = $(RT_S:rt/%.s=$(OBJ)/rt/%.o)
|
RT_WW = rt/append.ww
|
||||||
|
RT_OBJ = $(RT_S:rt/%.s=$(OBJ)/rt/%.o) $(RT_WW:rt/%.ww=$(OBJ)/rt/%.o)
|
||||||
|
|
||||||
# Cstage: one-time C bootstrap (see BOOTSTRAP.md). Built by `cc`.
|
# Cstage: one-time C bootstrap (see BOOTSTRAP.md). Built by `cc`.
|
||||||
# Goes away at v1.0, replaced by a checked-in stage-0 binary.
|
# Goes away at v1.0, replaced by a checked-in stage-0 binary.
|
||||||
@@ -191,6 +192,14 @@ $(BIN)/ww_ww: selfhost/cmd/ww/main.ww selfhost/cmd/wcc/mem.ww lib/os/os.ww \
|
|||||||
$(OBJ)/rt/%.o: rt/%.s $(BIN)/w6a | $(OBJ)/rt
|
$(OBJ)/rt/%.o: rt/%.s $(BIN)/w6a | $(OBJ)/rt
|
||||||
$(BIN)/w6a -o $@ $<
|
$(BIN)/w6a -o $@ $<
|
||||||
|
|
||||||
|
# ww-side runtime helpers (rt/*.ww): compile via w6c to .s, then w6a.
|
||||||
|
# Each .ww module is standalone — uses @symbol FFI for rt_alloc/rt_free
|
||||||
|
# rather than `use os;` so no bundling is required.
|
||||||
|
$(OBJ)/rt/%.s: rt/%.ww $(BIN)/w6c | $(OBJ)/rt
|
||||||
|
$(BIN)/w6c $< > $@
|
||||||
|
$(OBJ)/rt/%.o: $(OBJ)/rt/%.s $(BIN)/w6a | $(OBJ)/rt
|
||||||
|
$(BIN)/w6a -o $@ $<
|
||||||
|
|
||||||
$(LIB)/libwwrt.a: $(RT_OBJ) | $(LIB)
|
$(LIB)/libwwrt.a: $(RT_OBJ) | $(LIB)
|
||||||
$(AR) rcs $@ $(RT_OBJ)
|
$(AR) rcs $@ $(RT_OBJ)
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
// slices — generic slice helpers, written without generics.
|
// rt/append.ww — slice runtime helpers, archived into libwwrt.a.
|
||||||
//
|
//
|
||||||
// CLAUDE.md forbids generics, so we mint per-element-type variants.
|
// The compiler lowers `append(s, v)` to a CALL to one of these by
|
||||||
// Hare's `append` builtin is what these stand in for: each takes a
|
// element size (1 byte → appendu8, else → appendi64). User code
|
||||||
// *[]T plus an item, grows the storage if needed, and updates the
|
// never `use`s this — the symbol comes in via the runtime archive,
|
||||||
// slice header in place. The user passes `&s` because we mutate
|
// like rt_alloc and rt_streq.
|
||||||
// through the pointer.
|
|
||||||
|
|
||||||
use os;
|
@symbol("rt_alloc") fn alloc(n: u64) *void;
|
||||||
|
@symbol("rt_free") fn free(p: *void, n: u64) void;
|
||||||
|
|
||||||
export fn appendu8(s: *[]u8, v: u8) void = {
|
export fn appendu8(s: *[]u8, v: u8) void = {
|
||||||
if (s.len >= s.cap) {
|
if (s.len >= s.cap) {
|
||||||
let nc: i32 = s.cap * 2;
|
let nc: i32 = s.cap * 2;
|
||||||
if (nc < 8) { nc = 8; };
|
if (nc < 8) { nc = 8; };
|
||||||
let np: *u8 = os.alloc(nc: u64): *u8;
|
let np: *u8 = alloc(nc: u64): *u8;
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < s.len) {
|
for (i < s.len) {
|
||||||
np[i] = s.ptr[i];
|
np[i] = s.ptr[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
if (s.cap > 0) {
|
if (s.cap > 0) {
|
||||||
os.free(s.ptr: *void, s.cap: u64);
|
free(s.ptr: *void, s.cap: u64);
|
||||||
};
|
};
|
||||||
s.ptr = np;
|
s.ptr = np;
|
||||||
s.cap = nc;
|
s.cap = nc;
|
||||||
@@ -32,14 +32,14 @@ export fn appendi64(s: *[]i64, v: i64) void = {
|
|||||||
if (s.len >= s.cap) {
|
if (s.len >= s.cap) {
|
||||||
let nc: i32 = s.cap * 2;
|
let nc: i32 = s.cap * 2;
|
||||||
if (nc < 8) { nc = 8; };
|
if (nc < 8) { nc = 8; };
|
||||||
let np: *i64 = os.alloc((nc * 8): u64): *i64;
|
let np: *i64 = alloc((nc * 8): u64): *i64;
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < s.len) {
|
for (i < s.len) {
|
||||||
np[i] = s.ptr[i];
|
np[i] = s.ptr[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
if (s.cap > 0) {
|
if (s.cap > 0) {
|
||||||
os.free(s.ptr: *void, (s.cap * 8): u64);
|
free(s.ptr: *void, (s.cap * 8): u64);
|
||||||
};
|
};
|
||||||
s.ptr = np;
|
s.ptr = np;
|
||||||
s.cap = nc;
|
s.cap = nc;
|
||||||
@@ -244,24 +244,10 @@ static const struct row rows[] = {
|
|||||||
" x *= 2; x <<= 1; x >>= 2;\n"
|
" x *= 2; x <<= 1; x >>= 2;\n"
|
||||||
" return x;\n"
|
" return x;\n"
|
||||||
"};", 96 },
|
"};", 96 },
|
||||||
/* user-defined slice append via *[]u8: stdlib slices.appendu8.
|
|
||||||
* Demonstrates allocator + ptr-to-slice fields + scaled index write. */
|
|
||||||
{ "use os;\n"
|
|
||||||
"use slices;\n"
|
|
||||||
"fn main() i32 = {\n"
|
|
||||||
" let s: []u8;\n"
|
|
||||||
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
|
|
||||||
" slices.appendu8(&s, 65u8);\n"
|
|
||||||
" slices.appendu8(&s, 66u8);\n"
|
|
||||||
" slices.appendu8(&s, 67u8);\n"
|
|
||||||
" os.write(1, s.ptr, s.len: u64);\n"
|
|
||||||
" os.write(1, \"\\n\".ptr, 1u64);\n"
|
|
||||||
" return s.len;\n"
|
|
||||||
"};", 3 },
|
|
||||||
/* Hare-style builtins: append(s, v) and len(s). The compiler
|
/* Hare-style builtins: append(s, v) and len(s). The compiler
|
||||||
* lowers these to slices.appendu8 / s.len access. */
|
* lowers append to a CALL into libwwrt.a's appendu8 / appendi64
|
||||||
|
* by element size — no `use rt;` or `use slices;` required. */
|
||||||
{ "use os;\n"
|
{ "use os;\n"
|
||||||
"use slices;\n"
|
|
||||||
"fn main() i32 = {\n"
|
"fn main() i32 = {\n"
|
||||||
" let s: []u8;\n"
|
" let s: []u8;\n"
|
||||||
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
|
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
|
||||||
@@ -281,7 +267,6 @@ static const struct row rows[] = {
|
|||||||
"};", 12 },
|
"};", 12 },
|
||||||
/* variadic append + static qualifier (Hare idiom) */
|
/* variadic append + static qualifier (Hare idiom) */
|
||||||
{ "use os;\n"
|
{ "use os;\n"
|
||||||
"use slices;\n"
|
|
||||||
"fn main() i32 = {\n"
|
"fn main() i32 = {\n"
|
||||||
" let s: []u8;\n"
|
" let s: []u8;\n"
|
||||||
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
|
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
|
||||||
@@ -298,7 +283,6 @@ static const struct row rows[] = {
|
|||||||
"};", 25 },
|
"};", 25 },
|
||||||
/* Hare-style range loop: for (let x .. slice) iterates elements */
|
/* Hare-style range loop: for (let x .. slice) iterates elements */
|
||||||
{ "use os;\n"
|
{ "use os;\n"
|
||||||
"use slices;\n"
|
|
||||||
"fn main() i32 = {\n"
|
"fn main() i32 = {\n"
|
||||||
" let s: []u8;\n"
|
" let s: []u8;\n"
|
||||||
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
|
" s.ptr = nil; s.len = 0; s.cap = 0;\n"
|
||||||
@@ -309,7 +293,6 @@ static const struct row rows[] = {
|
|||||||
"};", 100 },
|
"};", 100 },
|
||||||
/* alloc([], n): fresh empty slice with cap n */
|
/* alloc([], n): fresh empty slice with cap n */
|
||||||
{ "use os;\n"
|
{ "use os;\n"
|
||||||
"use slices;\n"
|
|
||||||
"fn main() i32 = {\n"
|
"fn main() i32 = {\n"
|
||||||
" let s: []u8 = alloc([], 16);\n"
|
" let s: []u8 = alloc([], 16);\n"
|
||||||
" append(s, 72u8, 105u8);\n"
|
" append(s, 72u8, 105u8);\n"
|
||||||
@@ -317,7 +300,6 @@ static const struct row rows[] = {
|
|||||||
"};", 16 },
|
"};", 16 },
|
||||||
/* variadic spread: append(dst, src...) iterates src */
|
/* variadic spread: append(dst, src...) iterates src */
|
||||||
{ "use os;\n"
|
{ "use os;\n"
|
||||||
"use slices;\n"
|
|
||||||
"fn main() i32 = {\n"
|
"fn main() i32 = {\n"
|
||||||
" let src: []u8;\n"
|
" let src: []u8;\n"
|
||||||
" src.ptr = nil; src.len = 0; src.cap = 0;\n"
|
" src.ptr = nil; src.len = 0; src.cap = 0;\n"
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ static const char *modules[] = {
|
|||||||
"lib/bufio/bufio.ww",
|
"lib/bufio/bufio.ww",
|
||||||
"lib/fmt/fmt.ww",
|
"lib/fmt/fmt.ww",
|
||||||
"lib/net/net.ww",
|
"lib/net/net.ww",
|
||||||
"lib/slices/slices.ww",
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,6 @@ probe_dump_diff(const char *bin)
|
|||||||
"lib/types/types.ww",
|
"lib/types/types.ww",
|
||||||
"lib/sort/sort.ww",
|
"lib/sort/sort.ww",
|
||||||
"lib/path/path.ww",
|
"lib/path/path.ww",
|
||||||
"lib/slices/slices.ww",
|
|
||||||
"lib/net/net.ww",
|
"lib/net/net.ww",
|
||||||
"lib/encoding/utf8/utf8.ww",
|
"lib/encoding/utf8/utf8.ww",
|
||||||
"lib/encoding/hex/hex.ww",
|
"lib/encoding/hex/hex.ww",
|
||||||
|
|||||||
Reference in New Issue
Block a user