Add SP@ IR op, replace SOURCE/DEPTH/PICK with Forth (Phase 7)

New IrOp::SpFetch pushes the current data-stack pointer value, enabling
Forth-level stack introspection. This unblocks:

- DEPTH: `: DEPTH 5440 SP@ - 2 RSHIFT ;` (DATA_STACK_TOP - sp) / 4
- PICK: `: PICK 1+ CELLS SP@ + @ ;` direct memory read
- SOURCE: `: SOURCE 64 24 @ ;` reads INPUT_BUFFER_BASE + SYSVAR_NUM_TIB
- FALIGNED, SFALIGNED, DFALIGNED: address alignment (shadowed in boot.fth)

DEPTH and PICK are now compiled to native WASM — faster than the previous
host-function dispatch through call_indirect + Rust closure + mutex.

Removed ~109 lines of Rust. All 426 tests pass.
This commit is contained in:
2026-04-07 15:53:05 +02:00
parent 42f25a4c13
commit 58db238731
4 changed files with 48 additions and 109 deletions
+12 -1
View File
@@ -715,6 +715,17 @@ fn emit_op(f: &mut Function, op: &IrOp, ctx: &EmitCtx) {
dsp_reload(f);
}
IrOp::SpFetch => {
// Push the current cached DSP value onto the data stack.
// Save DSP, decrement, then store the saved value at new TOS.
f.instruction(&Instruction::LocalGet(CACHED_DSP_LOCAL))
.instruction(&Instruction::LocalSet(SCRATCH_BASE));
dsp_dec(f);
f.instruction(&Instruction::LocalGet(CACHED_DSP_LOCAL))
.instruction(&Instruction::LocalGet(SCRATCH_BASE))
.instruction(&Instruction::I32Store(MEM4));
}
// -- Compound operations -----------------------------------------------
IrOp::TwoDup => {
// ( a b -- a b a b )
@@ -982,7 +993,7 @@ fn is_promotable(ops: &[IrOp]) -> bool {
}
for op in ops {
match op {
IrOp::Call(_) | IrOp::TailCall(_) | IrOp::Execute => return false,
IrOp::Call(_) | IrOp::TailCall(_) | IrOp::Execute | IrOp::SpFetch => return false,
IrOp::If { .. }
| IrOp::DoLoop { .. }
| IrOp::BeginUntil { .. }