Ownership et libération ABI
Statut documentaire : reference — voir Maturité et preuves.
L'ownership est une donnée du contrat
Chaque descripteur de valeur porte une sémantique d'ownership : value, caller, owned-by-caller, owned-by-module, borrowed ou retained. Il enregistre séparément la façon de libérer : aucune, release du module, free du module ou méthode dédiée.
Ces informations sont indispensables aux bindings : la forme d'un pointeur natif ne permet pas de deviner qui doit libérer quoi.
Chemin de handle possédé testé
invocation constructeur
-> résultat handle
-> ownership = owned-by-caller
-> release kind = module release
-> utilisation dans des appels d'instance
-> release explicite
-> le wrapper ne possède plus de pointeur natif
Un wrapper .NET propriétaire doit traduire ce cycle en libération déterministe. Il ne doit pas utiliser l'allocateur hôte ni dépendre du finalizer comme mécanisme normal.
Borrowed contre owned
Un handle borrowed ne doit pas être libéré simplement parce que son wrapper managé disparaît. À l'inverse, un handle owned ne doit pas fuir parce que le binding a perdu l'information d'ownership.
La règle sûre est :
ownership du descripteur
-> politique du wrapper généré
-> comportement de libération déterministe
Texte et buffers alloués par le module
Le chemin d'erreur natif démontre la symétrie d'allocation : le module retourne un pointeur UTF-8, l'hôte copie le texte puis rend le buffer via free du même module.
Le même principe doit s'appliquer aux futurs strings, byte buffers, arrays et records traversant la frontière.
Les premiers contrats proposés pour les chaînes UTF-8 et les buffers d'octets utilisent donc une sémantique copie puis libération par le module pour les données produites par celui-ci.
Sécurité du release
Le wrapper public devrait rendre la libération idempotente même si l'ABI sous-jacente exige exactement un appel. Après release réussi, la référence native est effacée et les opérations nécessitant un objet vivant doivent échouer.
Affinité Runtime
Un handle n'a de sens que dans le runtime/module qui l'a créé. Les bindings générés doivent conserver cette affinité et rejeter l'utilisation d'un handle avec un autre contexte Runtime.