From 61fc3061a1a1f81b29c4e7f558604f53ec8702b5 Mon Sep 17 00:00:00 2001 From: Lassi Kortela Date: Fri, 19 May 2023 10:18:38 +0300 Subject: [PATCH] Add wget mirror wget --mirror --no-parent --no-host-directories --cut-dirs 3 \ https://www.ccs.neu.edu/home/lth/ffigen/ The following files are omitted from this commit: 960213.tar.gz ffigen.tar.gz lcc-3.4b.tar.gz robots.txt --- www/chez-policy.sch | 90 +++++++ www/chez.ps.gz | Bin 0 -> 51349 bytes www/index.html | 135 +++++++++++ www/manifesto.html | 241 +++++++++++++++++++ www/manifesto.ps.gz | Bin 0 -> 25398 bytes www/todo.html | 92 ++++++++ www/userman.html | 554 ++++++++++++++++++++++++++++++++++++++++++++ www/userman.ps.gz | Bin 0 -> 29662 bytes 8 files changed, 1112 insertions(+) create mode 100644 www/chez-policy.sch create mode 100644 www/chez.ps.gz create mode 100644 www/index.html create mode 100644 www/manifesto.html create mode 100644 www/manifesto.ps.gz create mode 100644 www/todo.html create mode 100644 www/userman.html create mode 100644 www/userman.ps.gz diff --git a/www/chez-policy.sch b/www/chez-policy.sch new file mode 100644 index 0000000..e602abf --- /dev/null +++ b/www/chez-policy.sch @@ -0,0 +1,90 @@ +; -*- scheme -*- +; +; Suggestions for policy mechanisms in the FFIGEN back-end for Chez Scheme. +; These are currently *not* implemented, and are only intended as examples. +; +; Mechanism falls into three categories: exclusion, overriding, and +; adaptation. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Exclusion: +; At the outset, everything in the .ffi file is marked as referenced. +; The mechanisms for excluding stuff are based on an item's name. + +; exclude-file takes a file name or list of file names and excludes every +; item defined in that file and files included by it. + +(exclude-file '()) + +; exclude-structure takes a structure name (i.e. either "struct FOO" +; or "union FOO" or "FOO") or list of names and inhibits generation of +; constructors, destructors, accessors, and mutators for it and all +; typedefs derived from it. If the name is a typedef name and the +; structure named has a compiler-generated tag, then the structure +; named by this typedef is also excluded. + +(exclude-structure "FILE") + +; exclude-function excludes the named function(s). + +(exclude-function "select") + +; exclude-global excludes the named global variable. + +(exclude-global "__iob") + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Overriding + +; Override-prototype gives the named function a new prototype. + +(override-prototype "fgets" + `(function (,(primitive-type 'string) + ,(primitive-type 'int) + ,(pointer-type (struct-type "FILE"))) + ,(pointer-type (primitive-type 'char)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Adaptation + +; Short-policy says something about how to handle shorts. Three values are +; possible: warning, use-integer, and use-proxy. If use-integer is the +; value, then an integer-32 FFI argument will be used on the assumption that +; this is meaningful in the native API. If use-proxy is the value then a +; proxy function is generated which takes an integer argument and calls +; the real function with the argument cast to short. + +(short-policy 'use-integer) + +; Struct-param-policy says something about how to handle structure parameters. +; Values are: warning and use-proxy. If use-proxy is the value, then +; an FF will be generated which takes structure pointers and which names a +; proxy function (this is transparent to Scheme code), and the real function +; will be called by the proxy. + +(struct-param-policy 'warning) + +; Struct-return-policy says something about how to handle structure return +; values. Values are: warning, alloc-new, and pass-placeholder. If alloc-new +; is the value, then a proxy function will be generated which receives +; the return value, allocates an object on the heap for it, copies the value +; into the allocated memory, and returns a pointer to the memory. +; If pass-placeholder is the value, then a FF and proxy will be generated +; that take an extra argument (the first); that argument must be a pointer +; to a structure in which to place the value. + +(struct-return-policy 'warning) + +; Variadic-policy says something about how to handle variadic procedures. +; Values are: warning and exclude. If the value is exclude, a warning will +; be given and no FFI code will be generated; if the value is warning, then +; invalid FFI code will be generated. + +(variadic-policy 'warning) + +; eof diff --git a/www/chez.ps.gz b/www/chez.ps.gz new file mode 100644 index 0000000000000000000000000000000000000000..cc1f33bbaaf1b00fa331b208bd071e706b588aaf GIT binary patch literal 51349 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 + +FFIGEN Home Page + + + +

FFIGEN

+ +"A good foreign function interface is 25% code and 75% policy." +
+

+ +FFIGEN (Foreign Function Interface GENerator) is a program suite that +facilitates the writing of translators from C header files to foreign +function interfaces for particular language implementations. + +

+ +* +FFIGEN Manifesto and Overview +(HTML) (ps.gz, 26 KB) +
+* +FFIGEN User's Manual +(HTML) (ps.gz, 30 KB) +
+* +FFIGEN Back-end for Chez Scheme Version 5 +(ps.gz, 52 KB) + +

+There are three motivating observations behind FFIGEN. The first is +that C header files are hard to parse because of the preprocessor, +general syntactic grunge, and the problem of getting the data layouts +right. The second is that foreign function interfaces differ widely and +that translations to different FFIs can't be the same, yet should share +work as much as possible. The third is that not all translations are +suitable for all purposes; there may be multiple valid translations - +each of which serves a different need - for any given language's FFI. + +

+ +For these reasons, a translator from C header syntax to an FFI should +have two parts: one target-independent front-end that translates from +the header file into a rational intermediate form and which can be used +with all translators, and a target-dependent back-end that translates +from the intermediate form to an FFI for the target system, using a +translation policy to guide the translation. This design nicely +facilitates writing back-ends for multiple languages, multiple FFIs per +language, and multiple policies per FFI. + +

+ +FFIGEN is a system that implements the split-translation philosophy. + +

    + +
  • The FFIGEN front-end is based on the front-end of the freely +available, production quality, ANSI C compiler lcc. Using +lcc makes +the FFIGEN front end portable, complete, and extensible for special +purposes. + +

    + +

  • The FFIGEN back-ends can be small (a back-end for Chez Scheme that +handles nearly all of C is 350 lines of Scheme code, for example), and +can be written in any language. Scheme is the preferred language for +back-ends right now, because the output syntax of the front-end, +although easily changeable, is that of S-expressions, and because a +back-end written in Scheme is already available for new back-ends to +build on. + +
+ +

+ +The current version of FFIGEN is available as a set of modifications to +lcc version 3.4b; you also need to get the lcc sources. +The FFIGEN +distribution includes documentation on how to write back-ends and a +documented example back-end for the FFI of Chez Scheme version 5. + +

+ This is a preliminary release of FFIGEN. It works, but +is neither complete nor polished. + +

+* +Click here to download the +full FFIGEN distribution. (148 KB) +
+This archive has not been updated with the fixes in the bug fix file (below). +

+* +Click here to download bug fixes up to February 13, 1996. (29 KB)
+Fixes to chez.sch to handle structs/unions that are declared but not +defined; function pointers; and unsigned shorts (a typo). Also a minor fix +to policy.sch to remove gratuitous non-standard-ness (use of reverse! rather +than reverse). Also included generated standard libraries for Chez Scheme +back-end (unknowingly left out of distribution). Unpack in lcc main +directory. +

+* +Click here to download an example of a Chez +Scheme policy file, left out of distribution. +

+* +Click here to download the lcc +3.4b distribution. +(965 KB) + +

+ +


+

+ +Related systems: + +

+ +

+


+

+ +The FFIGEN to-do list. + +

+lth@acm.org
+24 May 2000 + + diff --git a/www/manifesto.html b/www/manifesto.html new file mode 100644 index 0000000..1bfb05c --- /dev/null +++ b/www/manifesto.html @@ -0,0 +1,241 @@ + + + + +FFIGEN Manifesto and Overview + + + + +

+

FFIGEN Manifesto and Overview


+Lars Thomas Hansen
+lth@cs.uoregon.edu
+February 6, 1996 +
+ +
+

FFIGEN (Foreign Function Interface GENerator) is a program suite which +facilitates the writing of translators from C header files to foreign +function interfaces for particular language implementations.

+ +

On a more general level, FFIGEN is a statement about how such +translators should be structured for maximum usability, namely as a +single translator from C to a rational intermediate language and as +multiple translators from the intermediate language to separate FFI +translations. In the present document I motivate this two-level +structure by arguing that the many policy questions inherent in choosing +a mapping from one language to another cannot be accomodated in a single +translator, and that the two-level structure promotes significant code +reuse. Companion documents present the program suite itself.

+
+ +

1. Manifesto

+ +

Many language implementations have mechanisms which provide support for +call-outs to other, typically more primitive, languages. In particular, +implementations of very-high-level languages like Scheme, Common Lisp, +Standard ML, and Haskell support call-outs to system-level languages, +typically C. Other examples include the support for call-outs to C and +assembly language in C++, the EXTRINSIC directive in HPF, and the +<*EXTERNAL*> pragma in DEC SRC Modula-3. Mechanisms to call-out +to other languages are typically called foreign function +interfaces (FFIs). The purpose of an FFI is often to gain access to +functionality which is not (efficiently) expressible in the language +itself; other times the FFI is used to allow the program to interface to +existing libraries.

+ +

FFIs are only rarely part of the language definition; the only examples +I can think of are the support for C and assembly in C++ and the +EXTRINSIC directive in HPF. More typically, each language +implementation has its own idiosyncratic and often ad-hoc mechanism for +supporting foreign data types, functions, and variables. The mechanisms +are not standardized probably because they depend to a large extent on +the calling conventions of the procedure being called, the operating +system on which the program is running, the architecture of the machine, +the data types of the language being called, the version of the +compilers for the host and foreign languages, and so on. (In the +following I will refer to a point in the space made from the product of +the preceding attributes as a target.) Since the system +dependencies are considerable, it is unlikely that a fully general and +portable FFI can be defined for a language, and in addition, an +interface that works with all targets is likely to be neither functional +nor convenient. The chances for any portable, standardized language to +adopt a non-trivial FFI therefore seem slight. This is not to say that +an adequate job can't be done in many cases--for example, Franz Allegro +Common Lisp sports a sophisticated FFI which supports C and Fortran +seemingly very well--only that no standard and general +solution is likely to emerge.

+ +

Based on these observations, an approach to inter-language calling would +be to accept the fact that FFIs are implementation-dependent and instead +concentrate our effort on a higher level of abstraction: that of the +library interface. Even if the FFI is target-dependent, most of the +time the interface to a library is not (which is the beauty of an +interface in the first place). If, for each library, there existed a +reasonable definition of its interface, then a program could take that +definition and generate FFI code for the library for a given target. +This is the approach advocated by the creators of the ILU system (see +section 3).

+ +

However, manufacturers of libraries are not distributing +reasonable definitions of the interfaces to their libraries. All you +usually get is a C or C++ header file. A header file is not a +reasonable definition of the interface because of the baggage it +carries: nested include files, preprocessor macros, conditional +compilation, syntactic peculiarities, implementation language target +dependencies, and so on. In the best of all worlds, the manufacturer +would distribute the interfaces in an interface definition language like +the Object Management Group's IDL or ILU's ISL, and maybe one day that +will be common. In the mean time, we must fend for ourselves.

+ +

What we must do is to provide a translator which takes as its input not +a reasonable definition but instead a C or C++ header file or set of +header files, and produces as its output the FFI code for the library +for a given target. However, such a program is likely to be complicated +and there will be one version for each target. Maintaining all these +translators will be an unpleasant task. We could of course have one +translator, to IDL or ISL, and translators from the interface language +to the FFI, and as we will see, this is a variation on the mechanism +implemented by FFIGEN.

+ +

An additional important problem is that there is not one but several +translations for every target. A given interface can be translated to +any of several FFIs depending on the desired policy for the +translation. For example, consider a function + +

+  char *fgets(char*, int, FILE*).
+
+ +What does char* translate to? Consider the FFI provided by Chez +Scheme version 5. It has a string type which in a parameter +position causes the address of the first character of the string +argument to be passed to the function, but which in the return position +causes the characters to be copied from the storage pointed to by the +return value (if not NULL) into a fresh Scheme string. So if we +translate char* as string, we end up with (since +FILE* is translated as an unsigned int) + +
+  (define fgets
+    (foreign-function "fgets" 
+       (string integer-32 unsigned-32) 
+       string))
+
+ +which is expensive because the string is (needlessly) copied on return. +On the other hand, we can treat a char* as "just a pointer" and +translate as: + +
+  (define fgets
+    (foreign-function "fgets" 
+       (unsigned-32 integer-32 unsigned-32)
+       unsigned-32))
+
+ +but this does not let us access the characters in the buffer using +Scheme's string functions, since the buffer is not a string. In the +end, it appears that no fixed translation for char* is possible; +even if a fixed translation (and then: which one of them?) is adequate +in most situations, there will be special cases. (Arguably, it +would have been better for fgets() to return a truth value or the +number of characters read.)

+ +

The bottom line is, there is a lot of policy that goes into a +translation into a specific FFI. Hence we have a slogan (the core of +the Manifesto):

+ +
+A good foreign function interface is 25% code and 75% policy. +
+ +

It should be a goal, then, to separate the ardous task of parsing and +type-checking C headers and translating them into a rational +intermediate form, from the task of translating the intermediate form +into a FFI specification for a given target and translation policy.

+ +

2. The FFIGEN System

+ +

I have written a program, which I call ffigen, which takes +as its input a C header file and produces as its output a rational +translation of the interface defined by the header file. A rational +translation is one in which unnecessary or redundant syntax has been +removed, preprocessor macros have been expanded, and preprocessor +conditionals have been resolved so that definitions have been included +or excluded corrspondingly. The exact format of the intermediate code +is described in a companion document, the FFIGEN +User's Manual. ffigen functions as the front-end +of a system which translates C headers into foreign function +interfaces.

+ +

Each target system will have one or more specific back-ends which +take the intermediate form and produce translations for particular +targets and translation policies. Substantial parts of the back-end +code is largely target-independent and can therefore be shared by +multiple back-ends.

+ +

I have written one back-end to serve as a sample; it produces FFI code +for Chez Scheme version 5. It is documented in a companion document, +FFIGEN Back-end for Chez Scheme Version 5.

+ + +

3. Related Work

+ +

Kenneth B. Russell of MIT has implemented a system called Header2Scheme +which translates C++ to the FFI of the SCM Scheme system. FFIGEN and +Header2Scheme are fairly different at this point. My goal with FFIGEN +was to cover all of ANSI C including the preprocessor in a reasonable +way; this is doable because ANSI C is a small, fixed, and fairly simple +language. C++, on the other hand, is a very large, changing, and +complex language, and Header2Scheme therefore handles only part of it at +this time (as of version 1.2, it does not handle preprocessor macros, +typedefs, and enums). In addition, my emphasis was on not fixing policy +at all, which gives great freedom (and more work) to back-end writers, +whereas Russell has mostly fixed the policy. On the other hand, +Header2Scheme allows some policy decisions to be expressed in auxiliary +files given to the translator, and I have yet to experiment with these +mechanisms in FFIGEN. Header2Scheme is available from URL +

+http://www-white.media.mit.edu/~kbrussel/Header2Scheme
+
+

+ +

A message (<1996Jan17.121933.25825@chemabs.uucp>) posted +to the Usenet group comp.lang.scheme (among others) alleged that +Apple has a translator for their Dylan implementation which will take a +C header file and generate Dylan FFI glue for it. I know nothing else +about this system (but would appreciate hearing about it from anyone who +knows).

+ +

The ILU (Inter-Language Unification) system from Xerox PARC provides +cross-language calling functionality for modules which have interfaces +specified in ISL, the ILU interface definition language. ILU will take +the interfaces and produce stubs (glue, as it were) for the languages so +that they can call each other. The ISL file specifies the interface +somewhat abstractly in terms of data types which are meaningful in ISL +but which have various mappings in the target languages; again, one +mapping is assumed to fit all.

+ +

4. Acknowlegements

+ +

FFIGEN is based on the lcc ANSI C compiler. See the FFIGEN User's Manual for full acknowlegements +and a copyright notice.

+ +

This work has been supported by ARPA under U.S. Army grant +No. DABT63-94-C-0029, "Programming Environments, Compiler Technology +and Runtime Systems for Object Oriented Parallel Processing".

+ +
+
+lth@acm.org +
+24 May 2000 + + diff --git a/www/manifesto.ps.gz b/www/manifesto.ps.gz new file mode 100644 index 0000000000000000000000000000000000000000..cffd6118075c738acb16f553a12f074647730420 GIT binary patch literal 25398 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%0DTxz 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 literal 0 HcmV?d00001 diff --git a/www/todo.html b/www/todo.html new file mode 100644 index 0000000..da18f82 --- /dev/null +++ b/www/todo.html @@ -0,0 +1,92 @@ + + + +FFIGEN To-do list + + + + +

FFIGEN To-do list

+ +Updated 14 June 2000. + +

Intermediate format features

+ +
    +
  • Full ANSI C support: +
      +
    • [done] Bitfields. +
    • General support for type qualifiers. +
    +
  • Output a machine description. +
  • Output struct/union sizes. +
  • Output structure field offsets. +
  • Output line and column information. +
  • Retain and output comments. +
  • Output source file information (the name of the input file to + lcc -ffigen); this can + be useful since the back end can generate C files which + #includes the source header file. +
  • Support certain extensions: Microsoft __huge, __near, __far, __based, + __cdecl, __pascal; GNU __inline; others? +
+ +

Processing (both front-end and back-end)

+ +
    +
  • Some general support for a policy file? +
  • More intelligent macro-expansion support: macros should be expanded + as far as possible, and extraneous cruft should be removed so that the + back end can produce better translations. +
  • Support for some form of tokenized macros to support certain regular + and nice rewrites? C libraries like Open Inventor use macros + heavily in a virtual-function like style: +
    +   #define SoSphSetOverride(_this, state) \
    +       SoNodeSetOverride((SoNode *)_this, state)
    +
    + and it would be nice to provide some support for such cases in the form + of already-tokenized output. +
+ +

Implementation features

+
    +
  • Move to lcc 4.1, and ASDL. +
  • [done] Move to lcc 3.6. +
  • [done] Proper integration with lcc. Currently, it uses the lcc driver but + it generates code, performs assembly, and produces file.o (which it need + not do). In addition, the output file is called SYMBOLS but should + rather be called filename.ffi. +
+ +

Known bugs

+
    +
  • [done] Currently the rhs of a macro is output without any whitespace. This + is not correct if there are two adjacent identifiers or reserved words, + which happens in declarations (consider "const int blah"). [Harold] +
+ +

Back-ends

+
    +
  • Back-end for Scheme-to-C. +
  • Back-end for Gambit-C (Harold's got one working, it also does + interesting things with Open Inventor macros (see above)). +
  • Back-end for Tcl/Tk? +
  • Back-ends for ILU and Modula-3. +
  • Back-end for STk. +
  • Improvements to Chez Scheme back-end. +
+ +

Miscellaneous

+
    +
  • Advertise on lcc mailing list. +
+ +
+

+Press here to go to the FFIGEN home page. + +


+
lth@acm.org
+ + diff --git a/www/userman.html b/www/userman.html new file mode 100644 index 0000000..6205879 --- /dev/null +++ b/www/userman.html @@ -0,0 +1,554 @@ + + + + +FFIGEN User's Manual + + + + +
+

FFIGEN User's Manual


+(Preliminary)
+Lars Thomas Hansen
+lth@cs.uoregon.edu
+February 6, 1996 +
+ +

1. Introduction

+ +

FFIGEN is a program system which facilitates the writing of +translators from C header files to foreign function interfaces for +particular programming language implementations. This document +describes its structure and use. The discussion is aimed at translator +writers; everyone else should confine themselves to section 3. A +companion document, FFIGEN Manifesto and +Overview, motivates the work, and other companion documents describe +specific translator implementations. In particular, the document +FFIGEN Back-end for Chez Scheme Version 5 describes one +translator in detail.

+ +

FFIGEN is based on the lcc C compiler, which is copyrighted +software. See Section 10 for a full copyright notice.

+ +

2. Writing Translators

+ +

To generate a translation of a header file you run the ffigen +command to generate an intermediate form of the C header files you want +to translate, and then run the back-end on the resulting files to +generate the foreign function interface for the library.

+ +

Your task, should you choose to accept it, is to implement the +target-specific parts of the back-end for your particular target (which +is to say, combination of host language implementation, operating +system, architecture, foreign language implementation, and translation +policy). You should be able to use the FFIGEN front-end and the +target-independent parts of the back-end pretty much as they are.

+ +

How to implement the target-specific parts of the back-end is +discussed in Section 6. Use of the front end is described in Section 2. +The intermediate format is described in Section 4, and the +target-independent parts of the back-end and their interface to the +target-dependent part are described in Section 5. Finally, Section 7 +covers some issues which need to be tackled in the future.

+ +

3. Running FFIGEN

+ +

The command ffigen is run on a set of header files with +preprocessor option and include file options. Arguments are processed +in order. For each header file (type .h) and all the files it +includes, a single preprocessor file (type .ffi) is +produced.

+ +

The options are: +

+
-Dname[=value] +
Define preprocessor macro. +
-Uname +
Undefine preprocessor macro. +
-Idirectory +
Add directory to the beginning of the list +of include files. Standard directories include the lcc include +directory, /usr/include, and the current directory (in that order). +See the release notes for information about how to change the defaults. +
+ +ffigen performs full syntax and type checks on its input.

+ +The back-end is run by starting your favorite Scheme system and then +loading first the target-independent file process.sch and second +the target-dependent part of the translator; in the case of the Chez +Scheme back-end the file is called chez.sch. You then call the +procedure process with the name of the .ffi file to +process, as discussed in section 5. + +

4. Intermediate Format

+ +

The intermediate format consists of s-expressions following this grammar: + +

+  <file>      -> <record> ...
+  <record>    -> (function <filename> <name> <type> <attrs>)
+               | (var <filename> <name> <type> <attrs>)
+               | (type <filename> <name> <type>)
+               | (struct <filename> <name> ((<name> <type>) ...))
+               | (union <filename> <name> ((<name> <type>) ...))
+               | (enum <filename> <name> ((<name> <value>) ...))
+               | (enum-ident <filename> <name> <value>)
+               | (macro <filename> <name+args> <body>)
+  <type>      -> (<primitive> <attrs>)
+               | (struct-ref <tag>)
+               | (union-ref <tag>)
+               | (enum-ref <tag>)
+               | (function (<type> ...) <type>)
+               | (pointer <type>)
+               | (array <value> <type>)
+  <attrs>     -> (<attr> ...)
+  <attr>      -> static | extern | const | volatile
+  <primitive> -> char | signed-char | unsigned-char | short 
+               | unsigned-short | int | unsigned | long 
+               | unsigned-long | float | double | void
+  <value>     -> <integer>
+  <filename>  -> <string>
+  <name>      -> <string>
+  <body>      -> <string>
+  <name+args> -> <string>
+  <tag>       -> <string>
+
+ +Notes relating to the grammar:

+ +
    +
  • ... means "zero or more of" the preceding item. + +
  • The grammar is a little more general than the actual output +language. All structs, unions, and enums in parameter lists, return +types, and variable declarations are encoded as struct-ref, +union-ref, and enum-ref, respectively; structure, union, +and enum type definitions occur only in struct, union, +and enum records. + +
  • The <tag> field in structs/unions/enums (and their +-ref forms) is the tag. If one of these types +has a user-defined tag, then that tag is used in the struct-ref +item for the type; if the structure had no user-defined tag then a tag has been +generated by lcc. Generated tags have the syntax of positive +integers; in particular they start with a digit. There is one namespace +each for structs, unions, and enums. + +
  • +typedef names are not used anywhere: they occur in type +records only. + +
  • +The attributes on primitive types are const or volatile; the +attributes static and extern are used only on functions and +global variables. + +
  • +Functions which are known to take no parameters (ie t f(void)) have +one parameter, of type (void ()). The void type appears in a +parameter list only as the last element. + +
  • +Functions which take a variable number of arguments have at least one +defined non-void parameter and a last parameter of type (void ()). + +
  • +Functions for which no parameters were defined (ie t f()) have +no parameters. + +
  • +The ordering of records in the input has no relation to the +relative ordering of declarations in the original source. + +
  • +The <value> field in the array is its size. If the size is not +known, it is 0. + +
  • +Multidimensional arrays are represented as nested array types with the +leftmost dimension outermost in the expected way; i.e., it looks like +an array of arrays. + +
  • +Arrays are not valid return types. + +
  • +Array parameters lose some semantic information in the translation in +the current system. An array parameter t a[n] is always +converted to a pointer: (pointer t) regardless of whether +n is known or not. As expected, then, something like +t a[n][m][o] gets the parameter type +(pointer (array m (array o t))). Note that this only pertains to +parameter types; variables of array type are not converted in this manner. +(The semantic information claimed lost is the size of the leftmost +dimension. This lossage may make it impossible to perform array conversion +at call boundaries, for example.) + +
  • +The grammar describes the current format, which will change: line number +and column information will be incorporated. You should always use the +accessor functions defined in the target-independent part of the +back-end; see section 5. The grammar does not allow +for bit fields or qualifications on anything but primitive +types, but these will be accomodated eventually. + +
+ + +

5. The Target-Independent Back-End

+ +

The target-independent back-end is a Scheme program called +process which reads the intermediate form into memory and +performs some initial processing. It exports some global variables and +a number of procedures which are used to access the structures in the +database of intermediate records, and imports two target-dependent +functions from the target-dependent back-end. This section describes +the interfaces.

+ +

The global variables which hold the database are: + +

+    (define functions '())      ; list of function records
+    (define vars '())           ; list of var records
+    (define types '())          ; list of type records
+    (define structs '())        ; list of struct records
+    (define unions '())         ; list of union records
+    (define macros '())         ; list of macro records
+    (define enums '())          ; list of enum records
+    (define enum-idents '())    ; list of enum-ident records
+
+ +Each of these contains a list of all the records of the type indicated +by their names. Note that records may look different internally than +in the defined intermediate form, so accessor functions (see below) should +always be used.

+ +

In addition, there are two globals which are set but not used by +the target-independent back-end: + +

+    (define source-file #f)     ; name of the input file itself
+    (define filenames '())      ; names of all files in the input
+
+

+ +

The main entry point to the back end is the procedure process, +which takes a single file name as an argument. Process +initializes globals, reads the file, and processes the records. + +

+    (define (process filename) ...)
+

+ +

Record processing consists of some general analysis and target-specific +code generation. First, the target-specific procedure +select-functions is called; it must set or reset the +"referenced" bit in each record depending on whether the function is +interesting to the back-end or not. After computing reachability of +structured types and setting the referenced bits of those types which +are reachable, a translation is generated by a call to the back-end +function generate-translation, which takes no arguments. + +

+    (define (select-functions) ...)
+    (define (generate-translation) ...)
+

+ +

A number of data structure accessors and mutators are also available. +These are generic procedures which work on all of the record types. + +

+    (define (file r) ...)          ; file name of record
+    (define (name r) ...)          ; name in records which have one
+    (define (type r) ...)          ; type in records which have one
+    (define (attrs r) ...)         ; attrs in records which have one
+    (define (fields r) ...)        ; fields in struct/union record
+    (define (value r) ...)         ; value of enum-ident record
+    (define (tag r) ...)           ; tag in struct/union/union/-ref record
+
+    (define (referenced? r) ...)   ; is record referenced?
+    (define (referenced! r) ...)   ; set referenced bit
+    (define (unreferenced! r) ...) ; reset referenced bit
+
+ +Arguably the tag accessor should go away and name +should simply be used in its place. As it is, name is not +defined on struct-ref, union-ref, and +enum-ref records.

+ +

The procedure record-tag returns the tag of the record currently +being held. It can also be applied to types. + +

+    (define (record-tag r) ...)    ; get record tag
+

+ +

All records can have back-end specific values attached to them; usually +these are cached names for operations on structured values, so for now +the procedures which manipulate the back-end specific data are called +cache-name to remember a value and cached-names to return +the list of remembered values: + +

+    (define (cache-name r v) ...)  ; remember value in record
+    (define (cached-names r) ...)  ; retrieve remembered values
+
+ +We should probably replace this with a more general property-list-like +mechanism.

+ +

In addition, two procedures extract parts of function types: + +

+    (define (arglist r) ...)       ; function argument types
+    (define (rett r) ...)          ; function return type
+

+ +

Some utilities to deal with file names are also provided: + +

+    (define (strip-extension fn) ...)
+    (define (strip-path fn) ...)
+    (define (get-path fn) ...)
+

+ +

A string macro expander makes it easier to generate C code, for the back +ends that need it. The macro expander is called instantiate and +is called with a string template and a vector of arguments (which are +also strings). The template contains patterns of the form @n +where n is a single digit; when such a pattern is seen it is +replaced with the corresponding value from the argument vector. + +

+    (define (instantiate template arguments) ...)
+

+ +

Two procedures, struct-names and union-names, take a +structure (or union) and returns a list of all the typedef names which +reference the structure directly. + +

+    (define (struct-names struct) ...)
+    (define (union-names union) ...)
+

+ +

An association function which searches one of the record lists for a +given record by the name field is also available: + +

+    (define (lookup key items) ...)
+

+ +

The procedure user-defined-tag? determines whether a tag was +defined by the user or generated by the system: + +

+    (define (user-defined-tag? x) ...)
+

+ +

The procedure warn takes some arbitrary arguments and generates +a warning message on standard output: + +

+    (define (warn msg . rest) ...)
+

+ +

Some standard predicates take a type and test its kind: +primitive-type? is true if the argument is of a primitive type as +outlined in the grammar above; basic-type? is true if the +argument is a primitive type or a pointer type; array-type? is +true if the argument is an array type, and finally, +structured-type? is true if the argument is a struct-ref +or union-ref type: + +

+    (define (primitive-type? t) ...)
+    (define (basic-type? t) ...)
+    (define (array-type? t) ...)
+    (define (structured-type? t) ...)
+

+ +

6. Writing a Target-Dependent Back-End

+ +

To write the target-dependent back-end, you must decide on the policy +for the translation and then implement the translation. The policy +covers such issues as: which constructs in C are or are not handled; the +translation for each handled construct; how non-handled constructs are +dealt with (ignored, detected with warnings, detected with errors); how +to deal with exceptional cases (consider the fgets example from +the Manifesto).

+ +

For a concrete example, see the companion document FFIGEN Backend +for Chez Scheme Version 5, which addresses many of the choices to be +made and their possible solutions.

+ +

7. Future Work

+ +

A number of features will be supported in the future:

+ +
    +
  • There will be a line and a column field in each record, giving the +source line on which the identifier was defined. + +
  • Bitfields will be supported. + +
  • Qualifiers (what's now called attributes, that is, const and +volatile) will be supported on all types, not just on primitive +non-pointer types like now. + +
  • The intermediate representation will include the name of the orignal +input file, and its path. + +
  • The intermediate representation will include a representation of +the include file hierarchy which was traversed to produce the +intermediate representation. + +
+ +

A number of features will most likely be supported, but need +to be investigated:

+ +
    +
  • It would be nice to retain comments. + +
  • Various popular extensions to C are not currently supported by +lcc, but would be extremely useful: long long is used +extensively in Unix header files, and header files for compilers on PCs +often use the common Microsoft extensions __huge, __far, +and __near (and their non-underscore equivalents). Some C compilers +support __inline declarations, and although we can't generate +code for in-line procedures we can at least parse them if the compiler +can cope with __inline. (__inline is the easier, since it +can be ignored. The others must show up as type qualifiers or new types.) + +
  • The current shell-program driver will probably be replaced by +something based on the lcc driver. + +
  • I'm going to experiment with partial macro application in the +front end so that back-ends can have simple support for macro +definitions. Currently, for example, even something as simple as the +EOF macro will be ignored by the Chez Scheme back-end because its +form is "(-1)" rather than simply "-1". + +
  • Information about the layout of fields within structured types +should possibly be emitted; this information would be useful to +low-level FFIs which need byte offset and size to access the field of a +structure. + +
+ +

In addition, there are some issues to investigate in a larger +perspective:

+ +
    +
  • General (target-independent) support for useful policy mechanisms. + +
  • How well can the intermediate language support other front-ends? +I don't want to fall into the UNCOL pit, but it would be interesting to +see how languages which resemble C in their parameter passing mechanisms +(Pascal, Modula, Oberon) could be mapped onto the intermediate language. +This is not high priority with me, however. If I embark on supporting +another front-end language it will probably be (sigh) C++. + +
+ +

8. Please Contribute!

+ +

My goal is to support as many target languages as is reasonable, but I +can't write all the translators myself (I lack the time and, in many +cases, the knowledge). Targets that I will take care of include STk, +and, if no-one beats me to it, Scsh, both Scheme systems. Someone has +already volunteered to write the ILU back-end. Others are interested +in back-ends for Modula-3 and Mercury.

+ +

Volunteers for any translator back-end are welcome to e-mail me and +volunteer their help. I will coach, coordinate, and help out as much as +possible.

+ +

9. Credits

+ +

FFIGEN is based on the freely available lcc ANSI C compiler, +implemented by Christopher Fraser (of AT&T Bell Labs) and David Hanson +(of Princeton University).

+ +

I would like to thank Fraser and Hanson for producing such an excellent +system; lcc has been a joy to work with, and their book, A +Retargetable C Compiler: Design and Implementation, made the +implementation of the FFIGEN front end in the matter of roughly a single +work day possible. Would it be that all software was this clean!

+ +

The development of FFIGEN was supported by ARPA +under U.S. Army grant No. DABT63-94-C-0029, +``Programming Environments, Compiler Technology and Runtime Systems +for Object Oriented Parallel Processing''.

+ +

10. Copyrights

+ +lcc is covered by the following Copyright notice: + +
+

The authors of this software are Christopher W. Fraser and +David R. Hanson.

+ +

Copyright (c) 1991,1992,1993,1994,1995 by AT&T, Christopher W. Fraser, +and David R. Hanson. All Rights Reserved.

+ +

Permission to use, copy, modify, and distribute this software for any +purpose, subject to the provisions described below, without fee is +hereby granted, provided that this entire notice is included in all +copies of any software that is or includes a copy or modification of +this software and in all copies of the supporting documentation for +such software.

+ +

THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED +WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY +REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY +OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.

+ +

lcc is not public-domain software, shareware, and it is not protected +by a `copyleft' agreement, like the code from the Free Software +Foundation.

+ +

lcc is available free for your personal research and instructional use +under the `fair use' provisions of the copyright law. You may, +however, redistribute the lcc in whole or in part provided you +acknowledge its source and include this COPYRIGHT file.

+ +

You may not sell lcc or any product derived from it in which it is a +significant part of the value of the product. Using the lcc front end +to build a C syntax checker is an example of this kind of product.

+ +

You may use parts of lcc in products as long as you charge for only +those components that are entirely your own and you acknowledge the use +of lcc clearly in all product documentation and distribution media. You +must state clearly that your product uses or is based on parts of lcc +and that lcc is available free of charge. You must also request that +bug reports on your product be reported to you. Using the lcc front +end to build a C compiler for the Motorola 88000 chip and charging for +and distributing only the 88000 code generator is an example of this +kind of product.

+ +

Using parts of lcc in other products is more problematic. For example, +using parts of lcc in a C++ compiler could save substantial time and +effort and therefore contribute significantly to the profitability of +the product. This kind of use, or any use where others stand to make a +profit from what is primarily our work, is subject to negotiation.

+ +

Chris Fraser / cwf@research.att.com
+David Hanson / drh@cs.princeton.edu
+Fri Jun 17 11:57:07 EDT 1994

+
+ +
+
+lth@acm.org +
+24 May 2000 + + diff --git a/www/userman.ps.gz b/www/userman.ps.gz new file mode 100644 index 0000000000000000000000000000000000000000..70e7b4d840f16034dbb76a2da08f496d214c4ccf GIT binary patch literal 29662 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%0D_s<8 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 literal 0 HcmV?d00001