• src/syncterm/scripts/load/wrentest.wren src/syncterm/wren_bind.c wren_

    From Deuc¨@VERT to Git commit to main/sbbs/master on Monday, April 27, 2026 16:09:27
    https://gitlab.synchro.net/main/sbbs/-/commit/02259da7fd489d53a2b8bca7
    Modified Files:
    src/syncterm/scripts/load/wrentest.wren src/syncterm/wren_bind.c wren_host.c wren_host_internal.h
    Log Message:
    SyncTERM: Wren foreign-type tags + output-dispatch re-entry fix

    Three related changes shaken out by the wrentest suite:

    * Tag every wren_* foreign struct with a leading
    `enum syncterm_wren_foreign type` so foreign-method bodies can
    identify which foreign they hold (wrenGetSlotType only reports
    WREN_TYPE_FOREIGN, not the class). `slot_foreign_type()` reads
    the tag; `fn_Screen_writeRect` uses it to fast-path a Cells
    argument straight to ciolib_vmem_puttext with no copy or
    iteration, while still accepting a List of Cell.

    * Guard against wrenCall re-entry from inside fn_Conn_send /
    fn_Conn_sendRaw. Calling wrenCall while a foreign method is on
    the stack resets vm->fiber->stackTop (wren_vm.c:1464) and
    corrupts the outer fiber, producing unbounded recursion or
    SIGSEGV. fn_Conn_send now brackets conn_send with
    state.output_dispatching++/--, so wren_host_dispatch_output
    short-circuits for sends that originated inside Wren. C-side
    conn_send (terminal responses, modem keepalives) still fires
    hooks normally.

    * Drop wren_cell.parent (a raw pointer to a sibling Cells'
    foreign data, valid only as long as the Cells stayed in slot 0)
    and replace with parent_buf Ä the malloc'd vmem_cell buffer
    pointer captured at view creation, kept alive by the existing
    parent_handle pin. No raw foreign-data pointer held across VM
    calls, no scratch slot needed for cell_data().

    Plus test fixes in wrentest.wren: rect-roundtrip uses the natural
    readRect  mutate  writeRect(cells) shape; sentinel filter key
    0xFFFF -> 0xFE00 (ciolib's ungetch / rip_getch reassembly only
    re-composes a 16-bit key when the low byte is 0x00 or 0xe0); new
    T05 step issues `sleep 1 && printf` so the Hook.every wall-clock
    assertion is no longer racy on local PTYs.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net