Copyright (C) 2000-2012 |
GNU Info (g77-295.info)Alternate Entry PointsAlternate Entry Points (ENTRY) ============================== The GBE does not understand the general concept of alternate entry points as Fortran provides via the ENTRY statement. `g77' gets around this by using an approach to compiling procedures having at least one `ENTRY' statement that is almost identical to the approach used by `f2c'. (An alternate approach could be used that would probably generate faster, but larger, code that would also be a bit easier to debug.) Information on how `g77' implements `ENTRY' is provided for those trying to debug such code. The choice of implementation seems unlikely to affect code (compiled in other languages) that interfaces to such code. `g77' compiles exactly one public procedure for the primary entry point of a procedure plus each `ENTRY' point it specifies, as usual. That is, in terms of the public interface, there is no difference between SUBROUTINE X END SUBROUTINE Y END and: SUBROUTINE X ENTRY Y END The difference between the above two cases lies in the code compiled for the `X' and `Y' procedures themselves, plus the fact that, for the second case, an extra internal procedure is compiled. For every Fortran procedure with at least one `ENTRY' statement, `g77' compiles an extra procedure named `__g77_masterfun_X', where X is the name of the primary entry point (which, in the above case, using the standard compiler options, would be `x_' in C). This extra procedure is compiled as a private procedure--that is, a procedure not accessible by name to separately compiled modules. It contains all the code in the program unit, including the code for the primary entry point plus for every entry point. (The code for each public procedure is quite short, and explained later.) The extra procedure has some other interesting characteristics. The argument list for this procedure is invented by `g77'. It contains a single integer argument named `__g77_which_entrypoint', passed by value (as in Fortran's `%VAL()' intrinsic), specifying the entry point index--0 for the primary entry point, 1 for the first entry point (the first `ENTRY' statement encountered), 2 for the second entry point, and so on. It also contains, for functions returning `CHARACTER' and (when `-ff2c' is in effect) `COMPLEX' functions, and for functions returning different types among the `ENTRY' statements (e.g. `REAL FUNCTION R()' containing `ENTRY I()'), an argument named `__g77_result' that is expected at run time to contain a pointer to where to store the result of the entry point. For `CHARACTER' functions, this storage area is an array of the appropriate number of characters; for `COMPLEX' functions, it is the appropriate area for the return type; for multiple-return-type functions, it is a union of all the supported return types (which cannot include `CHARACTER', since combining `CHARACTER' and non-`CHARACTER' return types via `ENTRY' in a single function is not supported by `g77'). For `CHARACTER' functions, the `__g77_result' argument is followed by yet another argument named `__g77_length' that, at run time, specifies the caller's expected length of the returned value. Note that only `CHARACTER*(*)' functions and entry points actually make use of this argument, even though it is always passed by all callers of public `CHARACTER' functions (since the caller does not generally know whether such a function is `CHARACTER*(*)' or whether there are any other callers that don't have that information). The rest of the argument list is the union of all the arguments specified for all the entry points (in their usual forms, e.g. `CHARACTER' arguments have extra length arguments, all appended at the end of this list). This is considered the "master list" of arguments. The code for this procedure has, before the code for the first executable statement, code much like that for the following Fortran statement: GOTO (100000,100001,100002), __g77_which_entrypoint 100000 ...code for primary entry point... 100001 ...code immediately following first ENTRY statement... 100002 ...code immediately following second ENTRY statement... (Note that invalid Fortran statement labels and variable names are used in the above example to highlight the fact that it represents code generated by the `g77' internals, not code to be written by the user.) It is this code that, when the procedure is called, picks which entry point to start executing. Getting back to the public procedures (`x' and `Y' in the original example), those procedures are fairly simple. Their interfaces are just like they would be if they were self-contained procedures (without `ENTRY'), of course, since that is what the callers expect. Their code consists of simply calling the private procedure, described above, with the appropriate extra arguments (the entry point index, and perhaps a pointer to a multiple-type- return variable, local to the public procedure, that contains all the supported returnable non-character types). For arguments that are not listed for a given entry point that are listed for other entry points, and therefore that are in the "master list" for the private procedure, null pointers (in C, the `NULL' macro) are passed. Also, for entry points that are part of a multiple-type- returning function, code is compiled after the call of the private procedure to extract from the multi-type union the appropriate result, depending on the type of the entry point in question, returning that result to the original caller. When debugging a procedure containing alternate entry points, you can either set a break point on the public procedure itself (e.g. a break point on `X' or `Y') or on the private procedure that contains most of the pertinent code (e.g. `__g77_masterfun_X'). If you do the former, you should use the debugger's command to "step into" the called procedure to get to the actual code; with the latter approach, the break point leaves you right at the actual code, skipping over the public entry point and its call to the private procedure (unless you have set a break point there as well, of course). Further, the list of dummy arguments that is visible when the private procedure is active is going to be the expanded version of the list for whichever particular entry point is active, as explained above, and the way in which return values are handled might well be different from how they would be handled for an equivalent single-entry function. automatically generated by info2www version 1.2.2.9 |