Ho letto questo per fare riferimento alla scelta del modello di esecuzione, non all'esposizione di dettagli di livello inferiore dell'architettura hardware. Il CLR è principalmente una macchina stack, il che significa che gli opcode operano su una pila. L'altra opzione comune nello spazio di progettazione VM è la macchina di registro, dove invece viene manipolato un insieme (di solito illimitato) di registri virtuali. Questi registri sono un'astrazione fornita dalla VM (molto simile allo stack in alternativa), quindi è indipendente dall'hardware e deve essere mappato ai registri hardware per un'esecuzione più rapida. Esempi sono le VM Lua (sia l'implementazione di riferimento e LuaJIT), Dalvik e l'esperimento (per altri motivi) Python VM Falcon.
Se la mia lettura è corretta, le osservazioni si riferiscono semplicemente al fatto che è un po 'più facile generare opcode di stack da un AST piuttosto che generare opcode di registro. Su una VM stack, ciascuno (o almeno la maggior parte) dei nodi AST può generare opcode come questo:
child1.codegen()
...
childN.codegen()
emit(OPCODES_FOR_THIS_OPERATION)
ad esempio, per aggiunta:
lhs.codegen()
rhs.codegen()
emit(ADD)
Al contrario, una macchina virtuale basata sui registri ha bisogno di portare in giro almeno alcuni stati per gestire in quale registro sono inseriti tutti i valori temporanei. E se vuole evitare di usare troppi registri, alcune ottimizzazioni leggermente non banali sono necessario (per riutilizzare i registri o, più in generale, eseguire l'allocazione dei registri).