Cross-Language Interoberability in a Multi-Language Runtime

Matthias Grimmer


Abstract

In large-scale software applications, programmers combine different programming languages because it allows them to use the most suitable language for a given problem, to gradually migrate existing projects from one language to another, or to reuse existing source code. However, different programming languages have fundamentally different language implementations, which are hard to combine. The composition of these language implementations often results in complex interfaces between languages, insufficient flexibility, or poor performance.

We propose the Truffle-Multi-Language Runtime (TMLR), which can execute different programming languages and is able to compose them in a seamless way. The TMLR supports dynamic languages (e.g. JavaScript and Ruby) as well as statically typed lowlevel languages (e.g. C). It consists of Truffle language implementations, which translate source code to an intermediate representation that is executed by a shared virtual machine. The TMLR composes these different language implementations via generic access. Generic access is a language-agnostic mechanism that language implementations use to access foreign data or call foreign functions. It features language-agnostic messages that the TMLR resolves to efficient foreign-language-specific operations at run time. Generic access supports multiple languages, enables an efficient multi-language development, and ensures high-performance.

We evaluate generic access with three case studies. The first case study explains the transparent composition of JavaScript, Ruby, and C. The second case study shows an implementation of the C extensions API for Ruby. Finally, we show a case study that uses generic access to guarantee memory safety in C. We substitute native C allocations with managed data allocations, which demonstrates that the applications of generic access are manifold and not limited to cross-language interoperability. We can show that generic access guarantees good run-time performance. It avoids conversion or marshalling of foreign objects at the language boundary and allows the dynamic compiler to perform its optimizations across language boundaries.

Kurzfassung

Große Softwareprojekte werden oftmals in verschiedenen Programmiersprachen entwickelt, weil Teilprobleme in einer geeigneten Programmiersprache gelöst werden müssen, bestehende Projekte schrittweise in eine moderne Programmiersprache portiert werden müssen oder ein bestehender Programmcode wiederverwendet werden muss. Die Implementierungen verschiedener Programmiersprachen unterscheiden sich jedoch meist fundamental. Daher haben bestehende Verbindungsmechanismen in der Regel komplizierte Schnittstellen, sind nicht flexibel oder haben eine schlechte Laufzeitperformanz.

Wir stellen die Truffle-Multi-Language Runtime (TMLR) vor. Die TMLR ist eine Laufzeitumgebung, welche unterschiedliche Programmiersprachen ausführen und deren Implementierungen verbinden kann. Die Laufzeitumgebung unterstützt sowohl dynamisch typisierte Sprachen (z.B. JavaScript und Ruby) als auch statisch typisierte Sprachen (z.B. C) und besteht aus einzelnen Truffle-Implementierungen. Eine Truffle- Implementierung übersetzt ein Programm in eine Zwischenrepräsentation und führt diese auf einer gemeinsamen virtuellen Maschine aus. Die TMLR verwendet den Generic Access-Mechanismus um diese Implementierungen zu verbinden. Dieser Mechanismus ermöglicht einen sprach- und typunabhängigen Zugriff auf Objekte und Funktionen per Nachrichten. Die TMLR löst diese Nachrichten zur Laufzeit auf und ersetzt sie durch effiziente Zugriffsoperationen.

Wir evaluieren den Generic Access im Rahmen dreier Fallstudien. Die erste Fallstudie erklärt die transparente Verbindung von JavaScript, Ruby und C. Die zweite Fallstudie beschreibt die Implementierung des C Extensions API für Ruby. Als dritte Fallstudie zeigen wir, wie automatisch verwaltete Datenstrukturen für C verwendet werden können. Die Anwendungsgebiete des Generic Access sind vielfältig und nicht auf Interoperabilität zwischen Programmiersprachen beschränkt. Außerdem müssen Objekte an der Grenze zwischen Programmiersprachen nicht kopiert werden und der Generic Access ermöglicht dem dynamischen Übersetzer ein Programm unabhängig der verwendeten Sprachen zu optimieren. Das wiederum garantiert gute Laufzeitperformanz.


PhD thesis, Johannes Kepler University Linz, Oktober 2015

Download als pdf