Cours gratuits » Cours informatique » Cours programmation » Cours Oberon » Utilisation d'objets actifs d'Obéron l'interopérabilité des langages et compilation

Utilisation d'objets actifs d'Obéron l'interopérabilité des langages et compilation

Problème à signaler:

Télécharger



★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Utilisation d'objets actifs d'Obéron l'interopérabilité des langages et compilation [Eng]

L'interopérabilité des langues a été utilisée depuis l'apparition du deuxième langage de programmation, mais dans une moindre mesure, cette prise de conscience ne s'est produite que plus tard. Chaque fois que deux composants logiciels échangent des informations, ils doivent s'accorder sur un protocole commun pour pouvoir partager l'information: c'est l'interopérabilité au travail.

Internet est probablement l'exemple le plus connu d'interopérabilité entre systèmes. Il fournit l'infrastructure pour l'échange d'informations entre des machines hétérog&egr

ave;nes connectées via un réseau. Un système de base de données est également un exemple d'interopérabilité: les requêtes sont formées dans une application et soumises à la base de données via une interface logicielle bien définie, et les deux systèmes peuvent être implémentés en utilisant différents langages de programmation. Plus récemment, des plateformes entières dédiées à l'interopérabilité linguistique sont apparues: Microsoft .NET est l'exemple le plus récent jusqu'à présent, et il est conçu pour faire des programmes écrits en plus de deux une douzaine de langages impératifs et fonctionnels interagissent de manière complètement automatisée. En pratique, l'interopérabilité nécessite des normes et des protocoles clairs et acceptés pour l'échange d'informations.

Les composants logiciels sont la principale raison de l'émergence de l'interopérabilité, et de l'interopérabilité des langues en particulier. Les composants résolvent un problème de programmation spécifique et rendent les résultats disponibles aux autres composants via une interface. Les composants sont généralement mis en œuvre en utilisant le langage le mieux adapté pour résoudre le problème, et posent implicitement le problème de savoir comment faire communiquer des logiciels écrits dans différentes langues.

1.1 Motivation

L'interopérabilité est la capacité de deux ou plusieurs composants logiciels à coopérer malgré les différences de langage, d'interface et de plate-forme d'exécution [Weg96]. L'interopérabilité des langues se concentre sur la manière de gérer les différences dans les langages de programmation entre les composants logiciels.

L'interopérabilité linguistique présente de nombreux avantages évidents, ce qui reflète ses domaines d'application. Tout d'abord, il permet aux développeurs de composants de choisir le langage le plus approprié pour résoudre le problème, réduisant ainsi considérablement la complexité du logiciel. Deuxièmement, il permet et simplifie la réutilisation de logiciels existants écrits dans une langue différente. Troisièmement, l'interopérabilité des langages est également bénéfique pour les constructeurs de systèmes et de compilateurs, car elle nécessite et offre une infrastructure commune qui ne doit pas être répliquée dans le compilateur de chaque langue: pour cela, elle offre une plus grande l'abstraction temporelle, réduisant l'écart entre le langage et la plateforme à remplir par le compilateur.

1.1.1 La perspective du problème

Du point de vue du problème, le choix d'un langage approprié peut réduire considérablement la complexité d'un composant logiciel, ce qui est souvent le facteur limitant dans le développement de logiciels. Un langage de programmation est un outil pour construire un logiciel: il fournit des concepts primitifs pour raisonner sur des problèmes. Plus les composants du langage ou de la bibliothèque sont proches du problème, plus le programme est simple. La complexité est ensuite traitée et masquée par le compilateur qui convertit le programme dans l'environnement d'exécution sous-jacent. La complexité d'un programme est approximativement proportionnelle à sa taille, car elle correspond à peu près au nombre d'opérations de changement d'état utilisées dans le pro-gramme2; La complexité perçue du programme est donc la différence entre la complexité du problème et le niveau d'abstraction du langage. Il peut également arriver que le modèle de langage soit trop abstrait pour un problème, auquel cas le langage ne convient pas pour implémenter le problème. Cela peut être limité à une partie limitée de la langue. Dans d'autres cas, l'abstraction du langage peut être trop faible, auquel cas l'implémentation peut devenir très complexe, car la plupart des détails d'implémentation sont exposés au programme. Les quarante premières années de l'informatique ont vu la création de centaines de langages de programmation [Wex81, BG96], spécialisés dans les domaines d'application restreints. Ces langages simplifient et accélèrent le développement du logiciel, en réduisant l'écart entre le problème à résoudre et le langage. D'un autre côté, de nombreux langages génériques comme Algol 68, Ada, PL1, Clipper et C ++ ont également été créés, mais le plus souvent, ces langues ont énormément souffert sous leur propre complexité, car elles essayaient de répondre à tous les problèmes. problème avec une abstraction appropriée, ou offert seulement des primitives très simples qui n'étaient pas suffisamment expressives pour des problèmes complexes3.

1.1.2 La perspective de la composante

L'investissement dans le développement d'un composant logiciel peut être très élevé et le risque impliqué ne peut être ignoré4. La réutilisation de composants logiciels présente de nombreux avantages, notamment la disponibilité de solutions logicielles pour un problème bien défini qui ne coûte qu'une petite fraction du prix pour les développer, car leur prix est partagé entre tous les projets logiciels (ré) les utilisant. Une question fondamentale avec les composants est de savoir comment communiquer avec le reste du monde, en s'appuyant sur un standard d'interopérabilité. En fait, la plupart des standards de composants doivent définir comment représenter les données qu'ils utilisent pour communiquer et définir leurs interfaces de manière indépendante des langages. Les standards de composants comme COM, CORBA, JNI et RMI définissent un modèle de programmation, le séman¬ naire, et un langage pour définir leurs interfaces. La principale réalisation de ces normes consistait à ouvrir les frontières entre différents systèmes logiciels et à permettre leur interopérabilité. Cependant, la frontière reste, et la traverser ressemble plus à traverser une frontière d'état qu'une frontière de ville. JNI, par exemple, demande au développeur de convertir l'interface en utilisant certains outils, d'accéder à tous les champs à l'aide d'une méthode, et de prendre explicitement en compte l'épinglage des objets pour éviter leur collecte. Cette solution n'a pas la propagation automatique de l'interface du composant. CORBA souffre également du même problème: dans le projet GNOME, où les composants peuvent être accédés en utilisant différents langages de programmation, l'intervalle de temps entre la libération d'un composant et la sortie des wrappers depuis d'autres langues peut durer jusqu'à huit mois. dI02]. La plate-forme .NET de Microsoft améliore la situation en ajoutant les définitions d'interface5 aux composants et en forçant tout le langage à définir leurs interfaces en utilisant le modèle commun. De cette façon, chaque composant peut être compris par toutes les langues qui comprennent le modèle commun et il devient facilement disponible sans avoir besoin de créer des conversions d'interface. La disponibilité de solutions simples et bien intégrées pour la création et l'utilisation de composants logiciels jouera un rôle important dans la mise en place d'un développement et d'un marché orientés vers les composants.

1.1.3 La perspective du système et du compilateur

Fournir un support pour les composants et l'interopérabilité nécessite la création de systèmes logiciels pour fournir ce support. En particulier, ces systèmes doivent permettre de créer autour du modèle de composant qui devient le véhicule de toutes les informations dans le système. Ces systèmes nécessitent des capacités de réflexion pour pouvoir inspecter mais aussi concevoir les composants. Java a institutionnalisé l'utilisation de la réflexion à des fins d'inspection, dans .NET l'API de réflexion supporte les métadonnées et l'émission de code, Aos permet l'inspection et est agnostique en langue intermédiaire en autorisant plusieurs chargeurs (y compris éventuellement une gigue). La plate-forme commune est un gain énorme pour les développeurs de langages et de compilateurs, car elle fournit beaucoup de fonctionnalités, qu'ils devraient sinon concevoir eux-mêmes. Ceci est tout à fait évident lorsqu'on compare les JVM de Sable et de Jaos: dans Sable, la plupart des efforts ont été consacrés à la création d'un système complet, comme la conception des schémas de données, tandis que les principaux efforts de Jaos dans la cartographie de Javaâ € ™ s modèle d'objet au modèle objet d'Active Oberon et l'implémentation du compilateur juste-à-temps. Au cours des dernières décennies, les développeurs de langages ont souvent été confrontés au dilemme de la mise en œuvre d'un compilateur et d'un système ou de la traduction d'un langage en C (choix que la plupart d'entre eux ont pris, pour des raisons évidentes).

La transition d'un système de soutien à l'interopérabilité linguistique est moins difficile qu'il n'y paraît. En pratique, cela nécessite de déplacer certaines parties du compilateur, en particulier la table des symboles et éventuellement le back-end, vers le système pour être disponible pour tous les compilateurs.

Ainsi, la disponibilité d'une plate-forme logicielle exposant des services d'abstraction et de métadonnées de niveau supérieur est une simplification considérable pour les concepteurs de langages et de compilateurs, qui sont libérés de nombreux détails et deviennent des mappeurs de modèles au lieu des bit fiddlers.

1.2 Cette thèse

Cette thèse relate ma recherche sur l'interopérabilité des langues, documente le langage Active Oberon et son modèle basé sur Active Objects, et présente le compilateur Active Oberon Parallel Pacoâ et le Java. sur Aos â €? Jaosâ € ™ JVM études de cas.

Cette thèse étudie l'interopérabilité linguistique entre les composants logiciels ayant un modèle de programmation orienté objet. Nous limitons les langages considérés comme des langages de programmation impératifs mettant en œuvre un modèle orienté objet car ils sont basés sur les mêmes concepts et peuvent donc être comparés. Le modèle d'objet actif d'Active Oberon est utilisé comme référence.

La thèse montre que les différentes saveurs des modèles orientés objet sont en fait équivalentes. Il est possible de traduire un modèle dans un autre et de toujours transmettre la même information. Les idées communes d'orientation d'objet, de compatibilité de type entre les sous-types et de facettes d'objets (hérédité des spécifications) sont présentes dans toutes les variantes.

La thèse présente également le modèle d'objet actif utilisé dans le langage Oberon actif, et montre sa solidité et son utilité dans la construction de logiciels non triviaux comme un noyau entier, un système d'exploitation et un compilateur.

L'idée de réaliser l'interopérabilité par le partage d'informations sur les métadonnées et les structures de temps, et l'analyse des conversions entre les différents modèles d'objets sont assez simples et intuitives, alors que la réalisation de ces idées nécessite une quantité importante de logiciels montrer concrètement un exempleb.

Cette thèse apporte quelques contributions:

les différentes saveurs du modèle orienté objet utilisé dans quelques langages bien connus sont classées et les conversions parmi celles-ci sont détaillées, incluant la perte sémantique subie lors des transformations

le modèle d'objet actif utilisé dans Active Oberon est présenté; le rapport linguistique pour la langue elle-même est inclus, avec de nombreux exemples de structures concurrentes

6 assez grand pour une personne, mais pas pour les normes d'aujourd'hui, où la métrique «lignes de code» pour les produits logiciels est remplacée par le nombre de CD-ROM requis pour l'installer Active Oberon; un exemple non trivial, le compilateur Active Oberon lui-même implémenté dans Active Oberon est également présenté

Le compilateur Parallèle actif d'Oberon, Pacoâ, est présenté. Paco est un compilateur concurrent. En particulier, la concurrence est utilisée pour analyser les références en une seule passe. Un cadre de test pour les langages de programmation nommés â € ¢ Hostessà ¢ â,¬ est également présenté

le Java sur Aos â € "Jaosâ € ™ JVM est présenté. Jaos est une machine virtuelle Java pour le système Aos. Dans Jaos, l'API de réflexion est implémentée pour accéder au référentiel de métadonnées commun et ainsi assurer l'interopérabilité avec Active Oberon. Les incompatibilités entre Active Oberon et Java sont présentées

le noyau d'Aos est suffisamment complet pour supporter des systèmes autres qu'Oberon. Les mécanismes de plugin d'Aos peuvent être facilement utilisés pour autoriser plusieurs chargeurs et donc plusieurs langages intermédiaires sur la même plateforme

1.3 Aperçu

La thèse est composée de deux parties. La première partie de la thèse étudie l'interopérabilité des langues. La deuxième partie documente l'étude de cas utilisée pour étayer nos affirmations et recueillir des expériences.

Première partie

Le chapitre 2 introduit un cadre conceptuel basé sur le système en couches de Tanenbaum et la description du composant de Szyper-ski, et définit la terminologie utilisée tout au long de la thèse.

Le chapitre 3 présente l'interopérabilité des langues comme un problème de mappage de type; les contraintes d'une telle cartographie sont listées. Les modèles orientés objet de quelques langues sont classés et les mappages entre modèles, y compris les pertes sémantiques encourues, sont montrés.

Deuxième partie

Le chapitre 6 décrit la plate-forme Aos dans la perspective de l'interopérabilité. Ce chapitre présente le modèle de la plate-forme, et les conventions utilisées, en particulier l'interface binaire d'application (ABI), qui sont utilisées par les compilateurs Active Oberon et Java pour implémenter les fonctionnalités du langage. un schéma commun.

Le chapitre 4 présente les exigences sur un langage orienté objet fournissant la simultanéité, montre le modèle d'objet actif et inclut le rapport Active Oberon Language, une notation naturelle et de haut niveau pour décrire et implémenter l'objet actif sur le système Aos.

Le chapitre 5 décrit le compilateur Paco utilisé sur Aos; la table de symboles du compilateur est utilisée comme référentiel de métadonnées commun pour prendre en charge l'interopérabilité des langages; De plus, l'analyseur syntaxique simultané de Paco est documenté et utilisé comme exemple d'utilisation possible et élégante d'objets actifs. Un cadre pour les tests de régression linguistique appelé â € ¢ Hostessâ € ™ est également présenté.

Le chapitre 7 décrit la JVM de Jaos et les détails de sa mise en œuvre; le chapitre comprend une liste des facteurs limitant l'interopérabilité linguistique entre Oberon et Java.

Le chapitre 8 tire les conclusions de cette thèse, résume les résultats obtenus au cours de ce travail et propose quelques orientations futures de recherche.

Annexes

L'Annexe A.1 présente quelques exemples du langage Oberon actif montrant l'utilisation de la concurence dans la mise en œuvre de quelques algorithmes et structures bien connus.

L'annexe B dresse une liste de points qui pourraient être améliorés dans les langages Oberon et Active Oberon du point de vue du constructeur du compilateur.

2 Cadre conceptuel

Ce chapitre présente le cadre conceptuel utilisé tout au long de la thèse. Dans la section 2.1, une extension du modèle de système en couches de Tanenbaum est présentée; La section 2.2 explique les problèmes d'interopérabilité liés aux composants; SectionAos Approach introduit le système Aos en tant que plateforme d'interopérabilité linguistique; La section 2.4 classe les stratégies et les plates-formes existantes pour l'interopérabilité linguistique en utilisant le modèle et la terminologie utilisés dans le chapitre.

2.1 Système en couches

Dans cette section, un modèle pour décrire et classifier les systèmes informatiques et logiciels est introduit; ce modèle structure un système en une pile de couches avec un niveau d'abstraction croissant. Chaque couche est constituée de machines avec un langage propre et un modèle de programmation.

L'idée d'un système en couches a été introduite par Tanenbaum [Tan98]; nous étendons sa classification en ajoutant quelques notions supplémentaires au cadre conceptuel, qui sont alors utiles pour une meilleure compréhension des systèmes d'interopérabilité linguistique. La figure 2.1 montre un système en couches.

...

2.1.1 Langage de programme et de programmation

Un programme est la description formelle de la façon dont une tâche doit être exécutée. Il définit un ensemble de données qui doivent être manipulées par une séquence d'instructions.

Un langage de programmation est une notation formelle pour l'expression de programmes. Il consiste en un modèle pour exprimer des informations en utilisant des primitives de données avec une sémantique bien définie, et un ensemble d'instructions pour manipuler les données.

Les langages de programmation peuvent aller du langage machine, extrêmement flexible mais peu expressif, aux langages de programmation modernes qui définissent des abstractions hautement expressives. Les caractéristiques les plus importantes d'un langage sont le modèle de programmation qu'il utilise et les types de données qu'il gère.

Le modèle de programmation définit la sémantique et l'organisation du programme et des données, et comment le calcul est effectué. Les modèles possibles sont impératifs, orientés objet, fonctionnels et logiques.

Le type de données1 fournit un ensemble de types de primitives pouvant être utilisés dans un programme, définir la signification des données, leur emplacement et leur compatibilité avec d'autres données; ces caractéristiques diffèrent dans le niveau d'abstraction et de complexité. Certains systèmes de type utilisent la composition pour créer de nouveaux types définis par l'utilisateur (comme des tableaux et des structures).

Le modèle de programmation et le système de types reflètent le domaine d'application du langage. Le langage machine a un modèle de programmation impératif et un système de types définissant des registres2 et des emplacements de mémoire qui permettent n'importe quel type de données.

Les langages de haut niveau ont un modèle de programmation différent et plus abstrait; l'emplacement des données peut être une procédure locale ou à l'échelle du système (l'adresse exacte est masquée par l'abstraction), chaque donnée a un type précisément défini qui limite les opérations sur celle-ci. Certaines langues fournissent une large gamme de types de données, tandis que d'autres sont spécialisées dans des opérations particulières (par exemple, des chaînes ou des valeurs numériques).

2.1.2 Machines

Les machines exécutent des programmes; ils consistent en un langage de programmation et de stockage.

Les machines peuvent exister physiquement comme un microprocesseur, ou être des définitions purement théoriques, comme les machines virtuelles qui ne sont disponibles que dans les logiciels. Du point de vue conceptuel, cette distinction n'est pas pertinente, car les logiciels et le matériel sont logiquement équivalents. En pratique, il peut être avantageux d'avoir une machine implémentée par logiciel, car les modifications sont plus faciles à réaliser dans le logiciel; Ceci est courant pendant la phase de conception d'une machine.

Une machine n'a pas besoin d'être implémentée: des machines avec des propriétés mathématiques utiles peuvent être conçues pour aider à prouver les propriétés des autres machines construites dessus.

2.1.3 Bibliothèques

Les bibliothèques sont des collections de programmes qui remplissent un but. L'utilisateur d'une bibliothèque n'a pas besoin de se soucier de l'implémentation.

Les bibliothèques peuvent être considérées comme des instructions supplémentaires fournies par la langue, mais pour des raisons pratiques, elles sont traitées séparément, car ces instructions ne sont pas essentielles pour la langue.

A titre d'exemple, de nombreuses fonctions mathématiques présentes dans un langage en tant que primitives sont implémentées avec des fonctions de bibliothèque au cours de l'exécution, car le matériel n'en possède pas. Dans certains cas extrêmes comme le processeur ARM, chaque opération à virgule flottante est implémentée dans une bibliothèque, car il n'y a pas d'unité FPU.

2.1.4 Plates-formes

Les plates-formes fournissent un environnement d'exécution pour un programme; ils sont constitués d'une machine et d'un ensemble de bibliothèques, et reposent implicitement sur une interface binaire d'application (ABI), qui comprend une structure de données et une convention d'appel utilisée pour accéder aux bibliothèques. Les plates-formes sont les pierres angulaires sur lesquelles les systèmes sont construits.

Suivant cette définition, la machine virtuelle Java est en fait une plate-forme. Les classes de langage et les classes standard sont étroitement liées: les classes Object, String et Throwable sont implicitement utilisées dans le langage, bien qu'elles fassent partie de l'API standard [Szy98, p. 221]. Ce n'est pas le cas pour le byte-code Java, qui ne connaît que des références, mais n'a aucune connaissance d'une classe particulière.

2.1.5 Couches

Les couches regroupent les machines ayant des niveaux d'abstraction similaires. Les couches sont hiérarchisées, avec le matériel au niveau le plus bas et avec une abstraction croissante.

...

2.1.6 Across Layers: Abstraction et cartographie

L'abstraction est l'étape d'une couche inférieure à une couche supérieure. Elle consiste en la dissimulation, la composition et la restriction des fonctions de la machine (données et jeu d'instructions) pour créer une nouvelle machine.

Ces opérations peuvent être utilisées ensemble. La composition et la suppression sont de loin les étapes d'abstraction les plus utilisées: les primitives d'une couche ne sont pas disponibles dans une couche supérieure, mais des primitives plus expressives sont proposées, qui sont construites en regroupant les primitives de la couche inférieure.

En particulier, la suppression peut être utilisée pour créer une généralisation d'un groupe de machines, en masquant certaines primitives (ou seulement une partie de leur sémantique) et en gardant la partie commune à toutes les machines. A titre d'exemple, la suppression des informations de cadencement et des instructions spécifiques du microprocesseur à partir de la spécification d'un microprocesseur permet de créer une abstraction qui englobe tous les microprocesseurs d'une famille. Un autre exemple est l'abstraction de l'emplacement mémoire des données: les données sont allouées en pile ou en tas, l'adresse de données ne peut pas être définie ou interrogée dans la langue et reste dépendante de l'implémentation.

Le mappage est le passage d'une couche supérieure à une couche inférieure, le contraire de l'abstraction: les primitives de la couche sont traduites en groupes de primitives dans la couche inférieure avec un se-mantic équivalent. Les cas particuliers de cartographie ont un nom bien connu: la compilation est la traduction des programmes dans un langage d'une couche inférieure, tandis que l'interprétation est l'exécution interactive de programmes par l'intermédiaire d'un programme de la couche inférieure.

Créer de nouvelles machines ou de nouveaux langages en tant qu'abstractions de ceux qui existent déjà est rare. Les nouvelles ma-chines peuvent être conçues à partir de zéro indépendamment des machines sur lesquelles elles seront construites. Néanmoins, une cartographie doit exister (et symétriquement une étape d'abstraction), sinon ils restent une construction purement théorique. Souvent, l'écart sémantique entre deux couches peut être grand et la cartographie n'est pas évidente; l'introduction de couches intermédiaires peut réduire l'écart. Les ingénieurs logiciels sont de loin plus intéressés par la cartographie que par l'abstraction, car cela correspond aux algorithmes nécessaires pour implémenter une machine sur une plate-forme.

Pour être précis, une machine de niveau supérieur est généralement mappée à une plate-forme de niveau inférieur. Le mappage de certaines opérations (comme la nouvelle allocation de mémoire de code octet Java) peut être très complexe et souvent traduit en appel de bibliothèque pour plus de simplicité. Les bibliothèques peuvent être considérées ici comme des collections de modèles d'instruction communs, factorisés ensemble pour réduire la taille du code.


49