cgen: sub-slice cap = base_cap - lo
A sub-slice `base[lo:hi]` now sets cap to base_cap - lo (the storage remaining to the underlying end; Go/Hare-identical) instead of hi - lo (== len). base_cap is the array length N for [N]T, or the .capacity word carried in a slice/str header at +16. Authored once per stage in the cg_base_cap / cgbasecap helper, applied at both cap sites: the N_SLICE value path (which serves let-init since the prior commit) and the call-arg push. Both stages stay byte-identical (find-4 closed). cap arithmetic per ref/harec/src/eval.c:1017 (slice: slice.cap -= start) and eval.c:1024 (array: cap = array.length - start); capacity is a distinct field per ref/hare/rt/ensure.ha:4-8 and cap >= len per ref/harec/src/check.c:596. Only the cap arithmetic transfers: the ptr stays unscaled (lo*esz is #76) and eval.c's stricter start>=end bound is not ported (ww's runtime bound is start>end). str[lo:hi] yields str with a real .capacity (D1), so the str base uses the same +16 load -- no downgrade to []u8. base_cap falls back to len (prior behavior) where it isn't cleanly available: a non-ident base (its header cap was discarded by cgexpr; len is likewise wrong for a defaulted hi there, pre-existing) and a global str base (wwstage cgslice has no global-str load, #73 -- the carve-out keeps both stages byte-identical). Test: 942_subslice_cap_run, table-driven over both drivers, array / slice / str base + an append-no-realloc row, each shape chosen so base_cap-lo != hi-lo. Fold in three pre-existing fixtures that asserted the old cap == len and so failed under the corrected semantics (project #20): 681_arr_elem_field_write (slice_field_value_write, slice_field_ptr_write, slice_field_distinct_bytes), 693_dot_tagged_source (local_struct_slice_variant, via_ptr_slice_variant, letinit_slice_roundtrip, top_level_global_slice), and 695_match_bind_struct (slice_neg_control). Each cap word updated to base_cap - lo: a [8]u8 base sliced at lo=0 yields cap 8 (5->8, 3->8); distinct_bytes slices a [16]u8 at lo=0, yielding cap 16 (6->16). len / mark / ptr assertions are unchanged -- only the cap word moved.
This commit is contained in:
7
Makefile
7
Makefile
@@ -263,6 +263,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_str_chainfield_store_cap_run \
|
||||
$(BIN)/test_str_massign_store_cap_run \
|
||||
$(BIN)/test_slice_store_cap_run \
|
||||
$(BIN)/test_subslice_cap_run \
|
||||
$(BIN)/test_str_forrange_loopvar_run \
|
||||
$(BIN)/test_composite_call_arg \
|
||||
$(BIN)/test_composite_call_arg_run \
|
||||
@@ -690,6 +691,12 @@ $(BIN)/test_slice_store_cap_run: test/wcc/941_slice_store_cap_run.c \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_subslice_cap_run: test/wcc/942_subslice_cap_run.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_composite_call_arg: test/wcc/723_composite_call_arg.c \
|
||||
$(BIN)/w6c $(BIN)/w6c_ww | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
Reference in New Issue
Block a user