🐞Stack-Maschinen-Debugger

Ein eigener Lern-Interpreter führt die Beispielmodule Befehl für Befehl aus. Am Ende wird das Ergebnis mit der echtenWebAssembly.instantiate-Ausführung deines Browsers verglichen.

▶️Ausführen

Programm:
$factorial() (i32) → (i32)if/else · call · Rekursion (Call-Frames)43 Befehle ausgeführt
Schritt 1 / 44 · Tasten ← →
Aufruf $factorial(4): neuer Call-Frame, Parameter liegen in den ersten Locals.

🧾 $factorial (i32) → (i32)

0▶local.get 0 ;; $n
1i32.const 2
2i32.lt_s
3if (result i32)
4i32.const 1
5else
6local.get 0 ;; $n
7local.get 0 ;; $n
8i32.const 1
9i32.sub
10call 0 ;; $factorial
11i32.mul
12end
13end

▶ = nächster Befehl · ✓ = gerade ausgeführt

📚 Operanden-Stack

leer

Oben = zuletzt abgelegt (gelber Rand). Befehle nehmen ihre Operanden von oben.

🏷️ Locals von $factorial

0$nParameter · i324

🗂️ Call-Frames (1)

$factorial(4) · pc 0

🧠 Linearer Speicher (Bytes 0–127)

Dieses Modul hat keinen linearen Speicher.

⚖️ Vergleich mit der echten Engine

Lern-Interpreter… läuft
WebAssembly.instantiate…

Zum Ende springen (⏭), um das Ergebnis zu vergleichen.

🧠Was man hier sieht

💡 Operanden-Stack
Befehle haben keine Register-Operanden: i32.add nimmt die zwei obersten Werte und legt die Summe ab. Der Validator prüft vor der Ausführung, dass Anzahl und Typen an jeder Stelle stimmen.
💡 Locals & Call-Frames
Parameter sind die ersten Locals einer Funktion. Jeder call legt einen neuen Frame an – beifactorial(4) sieht man die Rekursion bis zur Tiefe 4.
✅ Strukturierter Kontrollfluss
Es gibt kein freies goto. br n springt zu einem umschließenden Label: beiblock/if an das Ende, bei loop an den Anfang.
⚠️ Linearer Speicher
Ein zusammenhängendes Byte-Array in Seiten à 64 KiB. Jeder Zugriff wird gegen die Größe geprüft – außerhalb gibt es einen Trap statt eines Speicherfehlers im Host.