Este artículo explica y compara cuatro estrategias para implementar el despacho de instrucciones en una máquina virtual (VM) escrita en Rust, todas basadas en la técnica de interpretación con tail-calls. La técnica consiste en transformar la recursión en un salto en tiempo de compilación, lo que evita reservar un nuevo marco de pila por cada instrucción y mantiene bajo el tamaño de la pila —una optimización especialmente útil en lenguajes funcionales como Scala.
El autor parte de una máquina de pila con cinco instrucciones (Lit, Add, Sub, Mul, Div) y replica en Rust los enfoques descritos por Noel Welsh para Scala, añadiendo variantes adaptadas a su proyecto de código ternario. En primer lugar, presenta el despacho con match recursivo usando la palabra clave become (una característica inestable de Rust) para garantizar la optimización de tail-call. A continuación, describe el "subroutine threading", donde cada instrucción se implementa como una estructura que satisface el trait Fn(), permitiendo llamadas dinámicas con &dyn Fn(). Después introduce el "indirect threading", que conserva el match pero utiliza recursión indirecta —las operaciones llaman a la función dispatch en lugar de retornar—, reduciendo un retorno de función por iteración. Por último, plantea variantes más idiomáticas en Rust, como una máquina de registros tradicional con etapa de decodificación adicional.
El propósito del texto es mostrar cómo estas técnicas funcionan en la práctica y animar al lector a experimentar con ellas en sus propios intérpretes. Aunque el contenido está cortado, la intención declarada del autor es completar la comparativa con benchmarks que midan el rendimiento real de cada enfoque en Rust, donde el optimizador del compilador ya aplica tail-call elimination en niveles altos de optimización.
