Bytecode précompilé
Compiler un script (lexer → parseur → codegen) a un coût. Pour un script qui change rarement mais est chargé à chaque démarrage de l'application hôte, YScript permet de précompiler une fois en bytecode et de ne charger que ce bytecode au démarrage, en s'épargnant l'analyse du texte source.
Précompiler (Dump)
Dump sérialise la fonction actuellement au sommet de la pile (donc après un Load réussi, avant de
l'appeler) vers un flux :
using YScript.Runtime;
using var engine = new ScriptEngine();
engine.OpenLibs();
if (engine.Load(File.ReadAllText("script.ys"), "script.ys") == ScriptStatus.Ok)
{
using var output = File.Create("script.ysc");
engine.Dump(output, strip: true); // strip = true : sans les informations de débogage
engine.Pop(); // la fonction chargée reste sur la pile après Dump
}
strip: true omet les informations de débogage (noms de variables locales, correspondance
ligne/adresse...) : fichier plus compact, mais des erreurs survenant dans ce bytecode ne pourront
plus être rapportées avec un numéro de ligne précis. Gardez strip: false tant que vous voulez des
messages d'erreur exploitables depuis le bytecode livré.
Charger du bytecode précompilé
Load/LoadFile acceptent aussi bien du texte source que du bytecode : le premier octet du flux
détermine automatiquement lequel des deux est en train d'être lu (signature binaire reconnue via
IScript.Signature). Aucune API séparée n'est nécessaire côté appelant :
using var input = File.OpenRead("script.ysc");
var status = engine.Load(input, "script.ysc", FileMode.Binary);
Le paramètre FileMode (Text/Binary/BinaryOrText, ce dernier étant la valeur par défaut) sert
de garde-fou plutôt que de sélecteur de format : passer FileMode.Binary fait échouer le chargement
si le flux contient en fait du texte (et inversement pour FileMode.Text), ce qui permet de refuser
explicitement l'un des deux formats plutôt que de laisser la détection automatique tout accepter —
utile si l'hôte ne veut charger que du bytecode de confiance et jamais compiler du texte arbitraire
à cet endroit, par exemple.
Le bytecode n'étant pas portable entre versions incompatibles du moteur ni vérifié par un
sandbox — au même titre que du bytecode Lua précompilé — ne chargez comme Binary que du contenu
produit par une version compatible de YScript et dans lequel vous avez confiance.
Sources de lecture (YScript.IO)
Load a trois surcharges, une par type de source :
| Surcharge | Usage |
|---|---|
Load(ITextReader, name) |
Source texte déjà en mémoire/flux caractère (toujours compilée, jamais interprétée comme bytecode) |
Load(Stream, name, mode) |
Flux brut, texte ou binaire selon mode |
Load(IFileReader, name, mode) |
Un IFileReader du moteur (voir IScriptHost.OpenReadFile), texte ou binaire |
LoadFile/DoFile passent par IScriptHost.OpenReadFile (donc par l'hôte configuré — voir
hote.md) plutôt que par System.IO directement, pour rester cohérents avec le reste de
l'accès fichier orchestré par l'hôte.
Les implémentations du namespace YScript.IO (StreamFileReader, TextFileReader,
TextBinaryFileReader, PreloadedFileReader, ...) sont surtout des détails internes utilisés par le
moteur et les hôtes fournis (DefaultHost/ConsoleHost) pour adapter un Stream/TextReader .NET
à IFileReader/ITextReader ; un hôte personnalisé n'a normalement pas besoin d'en écrire de
nouvelles, seulement d'implémenter IScriptHost.OpenReadFile/OpenFile en s'appuyant sur celles
existantes (voir l'implémentation de DefaultHost comme référence).