Stabilité de l'ABI
Introduction
Une interface binaire d'application (ABI) permet aux programmes d'appeler des fonctions et d'utiliser des structures de données d'autres programmes compilés. et d'utiliser les structures de données d'autres programmes compilés. Il s'agit de la version compilée d'une interface de programmation d'application (API). En d'autres termes, les fichiers d'en-tête décrivant les classes, les fonctions, les structures de données, les énumérations et les constantes qui permettent à une application d'effectuer une tâche donnée correspondent, par le biais de la compilation, à un ensemble d'adresses et d'informations attendues. compilation à un ensemble d'adresses et de valeurs de paramètres attendues, ainsi qu'à des tailles et à des dispositions de structures de mémoire avec lesquelles l'application peut fonctionner. de taille et de disposition des structures de mémoire avec lesquelles le fournisseur de l'ABI a été compilé.
L'application utilisant l'ABI doit être compilée de telle sorte que les adresses disponibles, les valeurs de paramètre attendues, et les tailles de la structure de mémoire et les mises en page sont d'accord avec celles avec lesquelles le fournisseur ABI a été compilé. Ceci est généralement accompli en compilant les en-têtes fournis par le fournisseur ABI.
En raison de l'utilisation de l'ABI à différents moments avec différentes versions du compilateur, une partie de la responsabilité d'assurer la compatibilité de l'ABI incombe au compilateur. Différentes versions du compilateur, éventuellement fournies par différents vendeurs, doivent toutes produire la même ABI à partir d'un fichier d'en-tête ayant un certain contenu, et doivent produire un code pour l'application utilisant l'ABI qui accède à l'API décrite dans un en-tête donné conformément aux conventions de l'ABI résultant de la description dans l'en-tête. Les compilateurs modernes ont la réputation de ne pas rompre la compatibilité ABI des applications qu'ils compilent.
La responsabilité restante de la compatibilité de l'ABI incombe à l'équipe chargée de la maintenance des fichiers d'en-tête qui fournissent l'API qui aboutit, lors de la compilation, à l'ABI qui doit rester stable. Des modifications peuvent être apportées aux fichiers d'en-tête, mais la nature des changements doit être suivie de près pour garantir que, lors de la compilation, l'ABI ne change pas d'une manière qui rendrait les utilisateurs existants de l'ABI incompatibles avec la nouvelle version.
Stabilité de l'ABI dans Node.js
Node.js fournit des fichiers d'en-tête gérés par plusieurs équipes indépendantes. Par exemple, les fichiers d'en-tête tels que node.h
et node_buffer.h
sont gérés par l'équipe Node.js. v8.h
est maintenu par l'équipe V8, qui, bien qu'en étroite collaboration avec l'équipe Node.js, est indépendante, et avec son propre calendrier et ses propres priorités. Ainsi, l'équipe Node.js n'a qu'un contrôle partiel sur les modifications introduites dans les en-têtes fournis par le projet. En conséquence, le projet Node.js a adopté la version sémantique. Cela garantit que les API fournies par le projet se traduiront par une ABI stable pour toutes les versions mineures et correctives de Node.js publiées dans une version majeure. En pratique, cela signifie que le projet Node.js s'est engagé à garantir qu'un addon natif Node.js compilé avec une version majeure donnée de Node.js se chargera avec succès lorsqu'il sera chargé par n'importe quelle version mineure ou corrective de Node.js dans la version majeure. version avec laquelle il a été compilé.
N-API
Il existe une demande pour doter Node.js d'une API qui permette d'obtenir une ABI stable sur plusieurs versions majeures de Node.js. La motivation pour créer une telle API est la suivante :
-
Le langage JavaScript est resté compatible avec lui-même depuis ses débuts, alors que l'ABI du moteur qui exécute le code JavaScript change avec chaque version majeure de Node.js. Cela signifie que les applications composées de paquets Node.js écrits entièrement en JavaScript n'ont pas besoin d'être recompilées, réinstallées ou redéployées lorsqu'une nouvelle version majeure de Node.js est introduite dans l'environnement de production dans lequel ces applications s'exécutent. En revanche, si une application dépend d'un paquetage contenant un addon natif, l'application doit être recompilée, réinstallée et redéployée chaque fois qu'une nouvelle version majeure de Node.js est introduite dans l'environnement de production. Cette disparité entre les paquets Node.js contenant des modules d'extension natifs et ceux qui sont entièrement écrits en JavaScript a alourdi la charge de maintenance des systèmes de production qui reposent sur des modules d'extension natifs.
-
D'autres projets ont commencé à produire des interfaces JavaScript qui sont essentiellement des implémentations alternatives de Node.js. Étant donné que ces projets reposent généralement sur un moteur JavaScript différent de celui de V8, leurs modules complémentaires natifs ont nécessairement une structure différente et utilisent une API différente. Néanmoins, l'utilisation d'une API unique pour un addon natif à travers différentes implémentations de l'API JavaScript de Node.js permettrait à ces projets de profiter de l'écosystème de paquets JavaScript qui s'est développé autour de Node.js.
-
Node.js pourrait contenir un moteur JavaScript différent à l'avenir. Cela signifie qu'extérieurement, toutes les interfaces de Node.js resteraient les mêmes, mais que le fichier d'en-tête V8 serait absent. Une telle mesure perturberait l'écosystème Node.js en général, et celui des modules d'extension natifs en particulier, si une API indépendante du moteur JavaScript n'est pas d'abord fournie par Node.js et adoptée par les modules d'extension natifs.
À ces fins, Node.js a introduit N-API dans la version 8.6.0 et l'a marqué comme un composant stable du projet à partir de Node.js 8.12.0. L'API est définie dans les en-têtes node_api. h
et node_api_types.h
, et fournit une garantie de compatibilité ascendante qui franchit la frontière de la version majeure de Node.js. La garantie peut être formulée comme suit :
Une version donnée n de la N-API sera disponible dans la version majeure de Node.js dans laquelle elle a été publiée, ainsi que dans toutes les versions ultérieures de Node.js, y compris les versions majeures ultérieures.
Un auteur d'addon natif peut profiter de la garantie de compatibilité ascendante N-API en s'assurant que l'addon n'utilise que les API définies dans node_api.h
et les structures de données et les constantes définies dans node_api_types.h
. Ce faisant, l'auteur facilite l'adoption de son addon en indiquant aux utilisateurs en production que la charge de maintenance de leur application n'augmentera pas plus par l'ajout de l'addon natif à leur projet qu'elle ne le ferait par l'ajout d'un package écrit uniquement en JavaScript .
La N-API est versionnée parce que de nouvelles API sont ajoutées de temps à autre. Contrairement au versionnement sémantique, le versionnement de la N-API est cumulatif. En d'autres termes, chaque version de la N-API a la même signification qu'une version mineure du système sémantique, ce qui signifie que toutes les modifications apportées à la N-API seront rétrocompatibles. En outre, les nouvelles N-API sont ajoutées sous un drapeau expérimental afin de donner à la communauté la possibilité de les tester dans un environnement de production. Le statut expérimental signifie que, bien que l'on ait veillé à ce que la nouvelle N-API ne doive pas être modifiée de manière incompatible avec l'ABI à l'avenir, elle n'a pas encore été suffisamment éprouvée en production pour être correcte et utile telle qu'elle a été conçue et, en tant que telle, elle peut subir des modifications incompatibles avec l'ABI avant d'être finalement incorporée dans une prochaine version de la N-API. En d'autres termes, une N-API expérimentale n'est pas encore couverte par la garantie de compatibilité future.