KIRK.TYM%office-2@sri-unix.UUCP (02/04/84)
From: Kirk Kelley <KIRK.TYM@office-2> I get the impression that a high overhead may be involved when switching runtime contexts in UNIX. For an extremely large hypertext system (AUGMENT) already implemented in a sophisticated procedure oriented compiled language (L10), we are thinking of compiling L10 I/O calls into machine code to emulate a C call on the stdio library for standard I/O functions needed by programs written in L10. I think this means having two different runtime contexts that get switched every time a call to a C procedure, like fopen, is made. So there are a variety of related questions here: * How much work do you have to do to safely launch a C-style call? Is it enough to save registers and use the right argument/result passing conventions, or will it also require allocated storage management facilities, error handlers of some type, or other rather involved things? and if so, how much work is it to emulate those facilities, and how heavy to maintain a whole C runtime and "swap" it somehow? * How will this affect the performance of applications written in L10 vs having the whole thing written in C? * Would 4.2BSD behave significantly different than, say, System V? * How about VAX vs 68000? * How farest the existing applications that do this? O unix wizards, we await your reply. -- kirk
gwyn%brl-vld@sri-unix.UUCP (02/05/84)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> Of course, the exact details of inter-language linkage depend on the specific machine architecture and on choices made by the language implementers. For most, perhaps all, UNIX C systems the "run-time context" is fairly simple: A procedure compiled by C expects information passed in a stack frame, which typically contains procedure-return address, pointer to previous frame, arguments to procedure, saved registers from calling context (except those specifically reserved for procedure return value). "Automatic" (procedure invocation local) variables are often allocated off the same stack, although this is not the only possible design. "Static" and "extern" (global) data is allocated once at link time. To successfully invoke a C procedure from another language, one needs to ensure that the proper calling frame is set up; this is usually fairly easy if there is a run-time stack, tricky otherwise. The return value of a C procedure is often passed in a general register, which is likely to be simple to deal with too. The main problem you encounter when using C library routines may be external name conflicts at link time, especially since STDIO routines invoke "read", "write", "open", etc. which may conflict with names chosen by the other language user (or, less likely, by the language run-time system implementor). Most UNIX systems support mixed F77 & C by making the assembly-level names generated for the same user-supplied name distinct; e.g. "open" becomes _open from C and _open_ from F77. C procedures require very little run-time support; you will probably need to supply malloc() and free() to allocate and free chunks of memory, since these routines are explicitly used by STDIO for buffer allocation (they are not technically part of the run-time system, but you will need them). Errors from UNIX system calls are handled by storing an error code into a global integer `errno' and returning a characteristic value (normally -1) from the syscall procedure. This is pretty minimal error handling; UNIX System V math library routines invoke a (user-supplied, if desired) matherr() routine upon error. The C environments on the VAX for UNIX System V and 4.2BSD differ very little. Since the MC68000 architecture is much like that of a VAX, I suspect that C/68000 run-time environment design is similar to C/VAX. The bottom line, then, is that you should have little trouble using C library routines from L10 if there are no global name conflicts with ANYthing in the C library that might be (indirectly) linked in support of the routines you explicitly invoke, if you provide a little call/ return linkage converter and malloc/free package, and if you have a run-time stack compatible with normal C needs. The execution cost of the interface to C is almost certain to be insignificant compared with the I/O operation cost. A very good discussion of C run-time requirements is in Bell Labs Computing Science Technical Report # 102, "The C Language Calling Sequence", by S. C. Johnson and D. M. Ritchie. One used to be able to get CSTRs for the asking from MH 2C-364 but I don't know if that is still true.
mark@umcp-cs.UUCP (02/11/84)
You can look at the code C itself uses to set up the environment it wants before calling the users "main" routine in /usr/src/libc/csu/crt.s (at least on our 4.1bsd system). 10 lines of assembler does it. Generally you won't have to do even this much--C carries around no assumptions about the environment it is in except that there be a stack. -- Mark Weiser UUCP: {seismo,allegra,brl-bmd}!umcp-cs!mark CSNet: mark@umcp-cs ARPA: mark@maryland