Fonctionnement interne du compilateur

Les décisions de conception clés qui rendent Perry rapide

01NaN-Boxing

Les valeurs sont stockées en floats 64 bits avec des motifs de bits spéciaux pour les pointeurs, permettant les types union sans overhead runtime. Cela permet à (string | number)[] de fonctionner efficacement.

En encodant les informations de type directement dans les bits de payload NaN IEEE 754, Perry évite le besoin de tagged unions ou de valeurs encapsulées. Un seul mot de 64 bits peut représenter n'importe quel type de valeur JavaScript — les nombres utilisent leur représentation naturelle, tandis que les chaînes, objets et autres valeurs allouées sur le tas utilisent des motifs de bits de pointeur qui tombent dans la plage NaN.

02Monomorphization

Les génériques sont spécialisés au moment de la compilation, comme en Rust. Chaque instanciation de type génère du code optimisé, éliminant l'overhead de vérification de type à l'exécution.

Quand vous écrivez Array'<'number'>' et Array'<'string'>', Perry génère deux implémentations séparées et entièrement optimisées. Cela signifie que les opérations sur les tableaux de nombres utilisent l'arithmétique machine directe — pas de type guards, pas de dispatch dynamique, pas de boxing.

03Static Dispatch

Pas de tables virtuelles. Les appels de méthodes sont résolus au moment de la compilation, permettant des appels de fonctions directs et des optimisations d'inlining.

Les runtimes OOP traditionnels utilisent des vtables pour la résolution de méthodes, ajoutant une couche d'indirection à chaque appel. Perry résout tous les appels de méthodes statiquement pendant la compilation, transformant les appels de méthodes d'interface en sauts directs. Cela débloque également un inlining agressif — les petites méthodes sont souvent intégrées directement dans leurs sites d'appel.

04Zero-Cost Abstractions

Les classes, interfaces et génériques TypeScript se compilent en code natif efficace sans overhead de représentation runtime.

Le système de types de TypeScript n'existe qu'au moment de la compilation — et Perry le prend littéralement. Les interfaces ne produisent aucun code runtime. Les hiérarchies de classes sont aplaties. Les contraintes génériques sont résolues en types concrets. Le binaire compilé ne contient que la logique réelle, sans la machinerie d'abstraction que les interpréteurs transportent habituellement.