Commit graph

7 commits

Author SHA1 Message Date
Stephen Dennis
caaf252cff test(lua): grow softcode↔Lua seam corpus (TC079–090, NESTED, STATE e4)
Beef residual coverage at the softcode JIT / Lua JIT boundary: production
nest shapes, host setq/attr survival, multi-entry lua(), mux.eval effects,
and float/nil/bool marshal consumers. Expand tests/luajit NESTED under
brackets-on and add STATE e4 so mux.eval cannot re-run silently.
2026-07-29 19:44:30 +00:00
Stephen Dennis
03ae705717 fix(softcode/jit): no AST re-run after host ECALL mid-run fail (#1791)
Softcode CALL_FUNC is already total (guest error strings, never
ECALL_DECLINE). The residual poison was mid-run DBT failure (code buffer
full, harvest miss) returning false → full AST re-run after effects.

Track eval_ctx::host_ecalls on softcode host ECALLs; after entry, commit
#-1 JIT POST-ENTRY FAIL instead of re-running. Document the audit in
plan-softcode-post-entry-contract.md and cross-link the Lua plan.
2026-07-29 13:17:18 -06:00
Stephen Dennis
414ea0ecca feat(lua/jit): CALL_VAL keeps call results as typed stack values
#1764 shape 2: default STRING-claim calls no longer marshal to TY_STRING
text immediately.  ECALL_LUA_CALL_VAL leaves the first pcall result on the
Lua stack and returns a TY_LUA_HANDLE.  Softcode boundary marshals via
ECALL_LUA_MARSHAL (fun_lua rules).  TEST/NOT use ECALL_LUA_TOBOOL so
tostring(0)/"" / string.find stay truthy under Lua semantics.

CALL_INT / CALL_VOID unchanged.  Equality of a value handle to a string
constant still declines (needs VM compare).

AGREE_DECLINE 16→12: the four #1764 if/not pins now execute.
2026-07-29 13:02:01 -06:00
Stephen Dennis
6f38d62b7b fix(lua/jit): equality compares Lua TYPES, not representations (#1770 review)
The EQK nil fix is right, and its lesson generalizes further than it was
applied.  Lua's == is false across TYPES, and HIR erases every
distinction that decides it: false and 0 are the same ICONST, nil and ""
the same empty SCONST, and the numeric path coerces "5" to 5.  Measured
on the PR as submitted -- all executing, all silently wrong:

  local a=0     if a == false   jit "y"  interp "n"
  local a=1     if a == true    jit "y"  interp "n"
  local a=false if a == 0       jit "y"  interp "n"
  local a="5"   if a == 5       jit "y"  interp "n"
  local a=5     if a == "5"     jit "y"  interp "n"

Generalizes the author's nil branch into a type-class test
(lua_type_class_of_value / _of_const, from the truth tag plus the HIR
type): mismatched classes are constant false whatever the
representations say; nil == nil stays true.

EQI needed the same treatment and is now its own case rather than
sharing CMP_RI: `a == 0` lowers to EQI and `a == ""` to EQK, so fixing
either alone leaves the other wrong -- the opcode-twin trap this PR's
own doc note names, one level deeper.  Order comparisons keep declining
instead: Lua RAISES on mismatched types there, so answering false would
be its own wrong answer.

Five AGREE pins across both opcode forms; all EXECUTE and answer like
the interpreter.  Plan gains the rule as item 5.

Also records the softcode no-post-entry-decline assumption that #1767's
exactly-once argument rests on -- derived today from the #1002 pre-entry
watermarks plus Phase 4 leaving one defensive ECALL_DECLINE that nothing
emits into, and therefore worth writing where it can be checked.

make test exit 0; smoke 1561/0; luajit PASSED.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 12:40:33 -06:00
Stephen Dennis
0efe4956ca fix(lua/jit): EQK must not treat nil as empty string
#1766's consumer audit covered CMP_RR (return t[2]=="") but not EQK
(if t[2]=="" then).  nil is the empty SCONST in HIR; EQK's STRCMP path
made nil == "" true compiled while the interpreter answers false.

Resolve EQK against the pool constant type and the lhs NIL tag before
STRCMP: nil==nil is true, nil vs anything else (including "") is false.
Tag pool TNIL/TFALSE/TTRUE on LOADK/LOADKX and on EQK's constant side.
Also refuse GTI/GEI on nil (order of nil).

Three EXEC-friendly AGREE pins for the if-EQK shapes.  Document the
"new value class ⇒ consumer audit" lesson (including opcode twins) in
the post-entry plan.
2026-07-29 12:22:12 -06:00
Stephen Dennis
20fe115a32 fix(lua/jit): allow effects on compiled path; close post-entry loud
Phase 4 deleted silent re-run, so #1750's effect-free corridor is obsolete:
bridge notify/pemit/set/eval run on both routes under the same permissions.
Remove EFFECT_REFUSED and compile-time effectful ineligibility.

STATE e2 delivers PING once on both legs. POST_ENTRY_LOUD 1→0;
AGREE_DECLINE 10→8 (mux.eval executes).

Docs: rewrite plan-lua-post-entry-contract as campaign-complete + residual
design goals; product plan points residual quality at §3.
2026-07-29 11:08:22 -06:00
Stephen Dennis
adb64b6fdb docs(lua): transition plan for post-entry decline/rerun contract (#1751)
File plan-lua-post-entry-contract.md as the multi-agent source of truth
for moving Lua from silent decline-then-rerun to softcode's eligibility
decides / run commits model. Point plan-lua-jit-product.md at it so
default-on is not read as architecture done.
2026-07-29 01:10:35 -06:00