Application Binary Interface Compatibility Through a Customizable Language
Total Page:16
File Type:pdf, Size:1020Kb
APPLICATION BINARY INTERFACE COMPATIBILITY THROUGH A CUSTOMIZABLE LANGUAGE by Kevin Jay Atkinson A dissertation submitted to the faculty of The University of Utah in partial fulfillment of the requirements for the degree of Doctor of Philosophy in Computer Science School of Computing The University of Utah December 2011 Copyright c Kevin Jay Atkinson 2011 All Rights Reserved The University of Utah Graduate School STATEMENT OF DISSERTATION APPROVAL The dissertation of Kevin Jay Atkinson has been approved by the following supervisory committee members: Matthew Flatt , Chair 11/3/2011 Date Approved Gary Lindstrom , Member 11/17/2011 Date Approved Eric Eide , Member 11/3/2011 Date Approved Robert Kessler , Member 11/3/2011 Date Approved Olin Shivers , Member 11/29/2011 Date Approved and by Al Davis , Chair of the Department of School of Computing and by Charles A. Wight, Dean of The Graduate School. ABSTRACT ZL is a C++-compatible language in which high-level constructs, such as classes, are defined using macros over a C-like core language. This approach is similar in spirit to Scheme and makes many parts of the language easily customizable. For example, since the class construct can be defined using macros, a programmer can have complete control over the memory layout of objects. Using this capability, a programmer can mitigate certain problems in software evolution such as fragile ABIs (Application Binary Interfaces) due to software changes and incompatible ABIs due to compiler changes. ZL’s parser and macro expander is similar to that of Scheme. Unlike Scheme, however, ZL must deal with C’s richer syntax. Specifically, support for context-sensitive parsing and multiple syntactic categories (expressions, statements, types, etc.) leads to novel strategies for parsing and macro expansion. In this dissertation we describe ZL’s approach to parsing and macros. We demonstrate how to use ZL to avoid problems with ABI instability through techniques such as fixing the size of class instances and controlling the layout of virtual method dispatch tables. We also demonstrate how to avoid problems with ABI incompatibility by implementing another compiler’s ABI. Future work includes a more complete implementation of C++ and elevating the ap- proach so that it is driven by a declarative ABI specification language. CONTENTS ABSTRACT :::::::::::::::::::::::::::::::::::::::::::::::::::: iii LIST OF FIGURES :::::::::::::::::::::::::::::::::::::::::::::: viii LIST OF TABLES ::::::::::::::::::::::::::::::::::::::::::::::: x ACKNOWLEDGEMENTS :::::::::::::::::::::::::::::::::::::::: xi CHAPTERS 1. INTRODUCTION :::::::::::::::::::::::::::::::::::::::::::: 1 1.1 Dissertation Statement . .3 1.2 Approach . .4 1.3 Contributions . .4 2. PROBLEMS WITH THE C++ ABI ::::::::::::::::::::::::::::::: 6 2.1 The C++ ABI . .6 2.2 The Problem of Fragile ABIs . .9 2.2.1 Solutions Within C++ . .9 2.2.2 Defining a Better ABI . 10 2.3 The Problem of Compiler Specific ABIs . 11 3. SOLVING ABI PROBLEMS :::::::::::::::::::::::::::::::::::: 12 3.1 Overview . 12 3.1.1 User Roles . 13 3.2 Adding Private Data Members . 14 3.2.1 Reserving Space Ahead of Time . 14 3.2.2 Storing the Private Data in a Separate Object . 16 3.2.3 Avoiding Direct Allocation . 17 3.2.4 Why Not a Fixed Set of Language Extensions? . 18 3.3 Adding New Virtual Methods . 19 3.4 Reordering . 20 3.5 Removing Members . 21 3.6 Migrating Method Upwards . 22 3.7 Adding Parameters . 22 3.8 Other Difficult Transformations . 22 3.9 A Better ABI . 23 3.10 Changing Compilers . 23 4. ZL OVERVIEW ::::::::::::::::::::::::::::::::::::::::::::: 25 4.1 ZL Primitives . 25 4.2 Macros . 26 4.3 Parsing and Expanding . 27 4.4 Procedural Macros . 28 4.5 The Class Macro . 32 5. USING ZL TO MITIGATE ABI PROBLEMS :::::::::::::::::::::: 33 5.1 Adding Data Members without Changing Class Size . 33 5.1.1 Fixing the Size of a Class . 34 5.1.2 Allowing Expansion . 36 5.1.3 Validation . 38 5.2 Fixing the Size of the Virtual Table . 38 5.3 A Better ABI . 38 5.4 Matching an Existing ABI . 40 5.5 Matching GCC’s ABI . 40 5.6 Matching Another ABI . 41 5.7 Other ABI Problems . 41 6. THE CASE OF A SIMPLE SPELL CHECKER ::::::::::::::::::::: 42 6.1 Simple Spell . 42 6.2 The Spell Checker API . 42 6.2.1 The Application API . 43 6.2.2 The Extension API . 45 6.3 A Simple Application and Binary Compatibility . 47 6.4 Adding a Filter, Compiled with GCC . 47 6.4.1 The Bridge Class . 47 6.4.2 Adding The Email Filter . 49 6.4.3 Automating the Creation of the Bridge Class . 50 6.5 Adding Support for a Personal Dictionary . 50 6.6 A Better ABI to Allow Future Enhancements . 54 6.7 A Simple Spell Checker, Version 2 . 59 6.8 An Opportunity for an Even Better ABI . 60 6.9 Comparison to a Real Spell Checker: Aspell . 60 7. USING ZL ::::::::::::::::::::::::::::::::::::::::::::::::: 62 7.1 Classes and User Types . 62 7.2 Pattern-Based Macros and Lexical Extensions . 64 7.2.1 Extending the Parser . 65 7.2.2 The Parser . 66 7.2.3 Built-in Macros . 66 7.3 Macro API . 68 7.3.1 The Syntax Object . 68 7.3.2 The Syntax List . 70 7.3.3 Matching and Replacing . 71 7.3.4 Match Patterns . 72 v 7.3.5 Creating Marks . 73 7.3.6 Controlling Visibility . 73 7.3.7 Fluid Binding . 74 7.3.8 Partly Expanding Syntax . 75 7.3.9 Compile-Time Reflection . 76 7.3.10 Misc API Functions . 77 7.4 Procedural Macro Implementation and State Management . 78 7.4.1 The Details . 78 7.4.2 Macro Libraries . 78 7.4.3 State Management . 80 7.4.4 Symbol Properties . 80 7.5 ABI Related APIs . 81 7.5.1 User Type and Module API . 81 7.5.2 User Type Builder . ..