w6c+wwstage: receive over-cap tuple sret returns at the call site (#10 Fold B)
Fold A made the CALLEE emit an over-capacity tuple return (> 4 GP or > 2
SSE eightbytes) via sret, but every receive site stayed loud-stopped, so
such a fn was not yet usefully callable. Fold B wires the call/receive end
by aligning every receive gate UP to the shared cg_sret_retsize() /
callsretsize() > 0 predicate (never a kind), per Rob's (B) ruling:
- single-var-let `let t = f();` cstage gate generalised from
TY_STRUCT&&>24 to cg_sret_retsize(lt)>0; the let's slot IS the
sret dest, the callee writes the whole tuple there, t.0/t.1 read
by offset. wwstage already keyed callsretsize (verified).
- N_ASSIGN-ident `t = f();` same generalisation; global arm
kept TY_STRUCT-only (a tuple-global has no sret-to-symbol path in
either stage). wwstage grows a tuple-local arm (rettupleof gates
it apart from the >24B-struct recv, which keeps its own path).
- destructure `let (a,b) = f();` and `a,b = f();` — the genuinely
new wiring: the callee sret's into the @sretscr discard slot, then
a copy-out loop moves each element to its binding at the SAME
packed offset the SEND wrote (foff += element size), each at its
natural width (#169); a `_` binding skips its store but advances
foff. Both stages, byte-identical.
- return-forward `return f();` cstage forward gate generalised
to the predicate, reusing cg_sret_forward verbatim. wwstage
already keyed sretretsize (verified).
The escape boundary stays loud: arg-pass `g(f())` fatals identically in
both stages (tuple arg exceeds return-cursor ABI capacity).
Test 799 is the runtime net Fold A deferred (byte-id is blind to a
SEND/RECEIVE layout mismatch): the bytes.cut-shaped ([]u8,[]u8) round-trip
over destructure / single-var-let / reassign / return-forward, each both
RUN under cstage and asserted cs==ww byte-identical. Tests 945 (row F)
and 956 (f64x3) flip from asserting the old over-cap loud-stop to
asserting the now-working sret round-trip. combined.ww amalgams (w6c +
wwdump embed the wcc cgen) regenerated. Unblocks #4 bytes.cut/rcut.
This commit is contained in:
11
Makefile
11
Makefile
@@ -345,6 +345,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_xmod_valglobal_dot_run \
|
||||
$(BIN)/test_len_strglobal_run \
|
||||
$(BIN)/test_tuple_sret_callee \
|
||||
$(BIN)/test_tuple_sret_receive_run \
|
||||
$(BIN)/test_widen_pad_zero_run \
|
||||
$(BIN)/test_named_ptr_alias_variant_widen \
|
||||
$(BIN)/test_single_field_struct_zeroinit \
|
||||
@@ -850,6 +851,16 @@ $(BIN)/test_tuple_sret_callee: test/wcc/798_tuple_sret_callee.c \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
# #10 Fold B (wide tuple-return / sret, RECEIVE side): the call/receive
|
||||
# end of the over-cap tuple ABI — single-var-let, destructure, reassign,
|
||||
# return-forward. Runtime round-trip (the net Fold A deferred — byte-id is
|
||||
# blind to a SEND/RECEIVE layout mismatch) + cs==ww byte-id. Self-contained
|
||||
# single-file probes (953 model), no selfhost traversal.
|
||||
$(BIN)/test_tuple_sret_receive_run: test/wcc/799_tuple_sret_receive_run.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
# #15: widening a bare *vtable into a NAMED-alias variant (`stream` =
|
||||
# *vtable) of `(file | stream)` must compute the right tag, not default
|
||||
# to tag 0. Both-stage byte-id + runtime, plus a degenerate-ambiguity
|
||||
|
||||
Reference in New Issue
Block a user